题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2038

就是莫队算法;

先写了个分块,惨WA:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=;
int n,m,K,c[maxn],rk[maxn],cnt[maxn],cnt2[maxn],ct=,t,tmp[maxn];
ll sum,s;
struct N{int l,r;ll ans,ans2;}q[maxn];
int rd()
{
int ret=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret;
}
bool cmp(int x,int y){return q[x].l<q[y].l;}
bool cmp2(int x,int y){return q[x].r<q[y].r;}
int C(int x){return x*(x-)/;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void yf(N &x)//&
{
ll k=gcd(x.ans2,x.ans);
x.ans/=k;x.ans2/=k;
}
void solve(int k)
{
sort(tmp+,tmp+t+,cmp2);
sum=;
memset(cnt,,sizeof cnt);
int L=k*K,R=L+;
for(int i=;i<=t;i++)
{
memset(cnt2,,sizeof cnt2);
while(R<=q[tmp[i]].r)
{
sum+=cnt[c[R]];cnt[c[R]]++;R++;
}
s=sum;
for(int j=L;j>=q[tmp[i]].l;j--)
{
s+=cnt[c[j]]+cnt2[c[j]];cnt2[c[j]]++;
}
q[tmp[i]].ans=s;
q[tmp[i]].ans2=C(q[tmp[i]].r-q[tmp[i]].l+);
yf(q[tmp[i]]);
}
}
int main()
{
n=rd();m=rd();K=sqrt(n);
for(int i=;i<=n;i++)c[i]=rd();
for(int i=;i<=m;i++)q[i].l=rd(),q[i].r=rd(),rk[i]=i;
sort(rk+,rk+m+,cmp);
for(int i=;(i-)*K<n;i++)
{
t=;
while(q[rk[ct]].l<=i*K&&ct<=m)tmp[++t]=rk[ct],ct++;
solve(i);
}
for(int i=;i<=m;i++)
printf("%lld/%lld\n",q[i].ans,q[i].ans2);
return ;
}

然后看了看题解,竟然是另一种做法,处理了一下式子:https://www.cnblogs.com/MashiroSky/p/5914637.html

所以抄了一下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=;
int n,m,K,c[maxn],cnt[maxn],blk[maxn];
ll ans;
struct N{int l,r,bh;ll a,b;}q[maxn];
int rd()
{
int ret=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret;
}
bool cmp(N x,N y){return blk[x.l]==blk[y.l]?x.r<y.r:blk[x.l]<blk[y.l];}
bool cmp2(N x,N y){return x.bh<y.bh;}
ll gcd(ll a,ll b){return a%b==?b:gcd(b,a%b);}
void update(int x,int val)
{
ans-=cnt[c[x]]*cnt[c[x]];
cnt[c[x]]+=val;
ans+=cnt[c[x]]*cnt[c[x]];
}
int main()
{
n=rd();m=rd();K=sqrt(n);
for(int i=;i<=n;i++)c[i]=rd(),blk[i]=(i-)/K+;;
for(int i=;i<=m;i++)q[i].l=rd(),q[i].r=rd(),q[i].bh=i;
sort(q+,q+m+,cmp);
for(int i=,l=,r=;i<=m;i++)
{
while(l<q[i].l)update(l,-),l++; while(l>q[i].l)update(l-,),l--;
while(r<q[i].r)update(r+,),r++; while(r>q[i].r)update(r,-),r--;
if(q[i].l==q[i].r)
{
q[i].a=;q[i].b=;continue;
}
q[i].a=(ll)ans-(r-l+); q[i].b=(ll)(r-l+)*(r-l);//(ll)!!!
ll k=gcd(q[i].a,q[i].b);//把分子放前面,万一分子是0
q[i].a/=k; q[i].b/=k;
}
sort(q+,q+m+,cmp2);
for(int i=;i<=m;i++)
printf("%lld/%lld\n",q[i].a,q[i].b);
return ;
}

...

然后又看到一篇博客:https://www.cnblogs.com/xuwangzihao/p/5199174.html

我的想法还是可以的嘛,加入一个点就是增加了之前有的这种点个数那么多的点对,所以维护点的个数即可;

主要是这个题不用严格按照分块来做,只是按分块排一下序就可以保证时间复杂度了,所以 l 和 r 直接全局移动就可以;

这样的话代码突然变得好优美...说到底自己那样的分块还是写得太丑,都不能保证正确呢...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=;
int n,m,K,c[maxn],cnt[maxn],blk[maxn];
ll ans;
struct N{int l,r,bh;ll a,b;}q[maxn];
int rd()
{
int ret=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret;
}
bool cmp(N x,N y){return blk[x.l]==blk[y.l]?x.r<y.r:blk[x.l]<blk[y.l];}
bool cmp2(N x,N y){return x.bh<y.bh;}
ll C(ll x){return x*(x-)/;}
ll gcd(ll a,ll b){return a%b==?b:gcd(b,a%b);}
void pop(int x){cnt[c[x]]--;ans-=cnt[c[x]];}//注意顺序
void push(int x){ans+=cnt[c[x]];cnt[c[x]]++;}
int main()
{
n=rd();m=rd();K=sqrt(n);
for(int i=;i<=n;i++)c[i]=rd(),blk[i]=(i-)/K+;
for(int i=;i<=m;i++)q[i].l=rd(),q[i].r=rd(),q[i].bh=i;
sort(q+,q+m+,cmp);
for(int i=,l=,r=;i<=m;i++)
{
while(l<q[i].l)pop(l),l++;
while(l>q[i].l)push(l-),l--;
while(r<q[i].r)push(r+),r++;
while(r>q[i].r)pop(r),r--;
q[i].a=ans;
q[i].b=C(r-l+);
ll k=gcd(q[i].a,q[i].b);//把分子放前面,万一分子是0
q[i].a/=k; q[i].b/=k;
}
sort(q+,q+m+,cmp2);
for(int i=;i<=m;i++)
printf("%lld/%lld\n",q[i].a,q[i].b);
return ;
}

bzoj2038 小Z的袜子(hose)——莫队算法的更多相关文章

  1. BZOJ2038: [2009国家集训队]小Z的袜子(hose) -- 莫队算法 ,,分块

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 3577  Solved: 1652[Subm ...

  2. [BZOJ2038] [2009国家集训队]小Z的袜子(hose) 莫队算法练习

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 10299  Solved: 4685[Sub ...

  3. BZOJ2038 小Z的袜子 (莫队算法)

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2038 专题练习: http://acm.hust.edu.cn/vjudge/conte ...

  4. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Subm ...

  5. kyeremal-bzoj2038-[2009国家集训队]-小z的袜子(hose)-莫队算法

    id=2038">bzoj2038-[2009国家集训队]-小z的袜子(hose) F.A.Qs Home Discuss ProblemSet Status Ranklist Con ...

  6. 【bzoj2038】[2009国家集训队]小Z的袜子(hose) 莫队算法

    原文地址:http://www.cnblogs.com/GXZlegend/p/6803860.html 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终 ...

  7. [bzoj2038][2009国家集训队]小Z的袜子(hose)——莫队算法

    Brief Description 给定一个序列,您需要处理m个询问,每个询问形如[l,r],您需要回答在区间[l,r]中任意选取两个数相同的概率. Algorithm Design 莫队算法入门题目 ...

  8. BZOJ2038: [2009国家集训队]小Z的袜子(hose) 莫队算法

    要使用莫队算法前提 ,已知[l,r]的答案,要能在logn或者O(1)的时间得到[l+1,r],[l-1,r],[l,r-1],[l,r+1],适用于一类不修改的查询 优美的替代品——分块将n个数分成 ...

  9. Bzoj 2038---[2009国家集训队]小Z的袜子(hose) 莫队算法

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色 ...

随机推荐

  1. SPOJ LCS2 多个串的最长公共子串

    这里串最多有10个,找所有串的最长公共子串 这里后缀自动机做,以第一个串建立后缀自动机,后面的串一个个去匹配,每次得到当前串在可到达状态上所能得到的最长后缀长度 拿所有串匹配后得到的结果进行计算 #i ...

  2. HDU1686 计算模式串匹配的次数

    题目大意: 输入一个T,表示有T组测试数据: 每组测试数据包括一个字符串W,T,T长度大于W小于1000000,w长度小于10000,计算W匹配到T中成功的次数: 这题很明显要用KMP算法,不然很容易 ...

  3. openGL加载obj文件+绘制大脑表层+高亮染色

    绘制大脑表层并高亮染色的工作是以openGL加载obj文件为基础的,这里是我们用到的原始程序:只能加载一个obj文件的demo. 然而,一个完整的大脑表层是由很多分区组成的,因此我们的程序需要支持两个 ...

  4. 6572平台上关于wifi热点切换跳的坑

    最近在做一个无屏的项目,需要开启设备的wifi热点,通过连接热点设置设备wifi,本来看起来很容易完成的一件事情,遇到了一下的坑 在wifi切换状态时,大概率出现不能切换的问题,比如从wifi状态切换 ...

  5. Codeforces917D. Stranger Trees

    $n \leq 100$的完全图,对每个$0 \leq K \leq n-1$问生成树中与给定的一棵树有$K$条公共边的有多少个,答案$mod \ \ 1e9+7$. 对这种“在整体中求具有某些特性的 ...

  6. centos 中找不到 php-config

    两种解决方式: 1.CentOS6 PHP extension install: Cannot find php-config. Please use --with-php-config=PATH 2 ...

  7. HashMap排序的问题

    那么已知一个HashMap<Integer,User>集合, User有name(String)和 age(int)属性.请写一个方法实现对HashMap 的排序功能,该方法接收 Hash ...

  8. 下一代的中间件必须是支持docker规范的

    下一代的中间件必须是支持docker规范的,这是中间件技术走向标准规范化的必经之路. 什么是 Docker? 答案是:Docker 是下一代的云计算模式.Docker 是下一代云计算的主流趋势. Do ...

  9. 项目中遇到的HQL查询问题

    问题描写叙述: 目的:想要查询出全部最新版本号的组件 说明:组件:版本号 =1:n关系 ,假设这个组件仅仅有一个版本号也要可以查出来. 项目中使用的是内存数据库,无法看到表结构,这里的样例仅仅用于模拟 ...

  10. ES文件浏览器 WIFI 查看电脑文件怎么弄

    1 开启来宾账户   2 右击要共享的文件夹,添加Guest共享(如果只是要查看共享的资源,权限级别为读取即可)   3 共享之后,网络路径就是"\\"+你的计算机名+" ...