【BZOJ1878】【SDOI2009】 HH的项链
莫队模板题,比较简单
原题:
HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。
N ≤ 50000,M ≤ 200000
莫队模板题
计算贡献的方法就是记一个cnt[i]表示值为i的有几个,每次扩张给cnt[i]+1或-1,当cnt[i]由0变成1或由1变成0时给答案+1或-1就行了
莫队框架不难(就是个按块排序然后左右扩张),关键点就在于如何O(1)计算贡献
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 using namespace std; 8 int rd(){int z=0,mk=1; char ch=getchar(); 9 while(ch<'0'||ch>'9'){if(ch=='-')mk=-1; ch=getchar();} 10 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 11 return z*mk; 12 } 13 struct dcd{int l,r,id;}b[210000]; 14 int n,m,a[51000]; int blck; 15 int cnt[1100000]; 16 int ans[210000]; 17 int mdf(int x,int y){ 18 if(y==1) return ++cnt[x]==1?1:0; 19 else return --cnt[x]==0?-1:0; 20 } 21 bool cmp(dcd x,dcd y){ return (x.l/blck==y.l/blck)?(x.r<y.r):(x.l/blck<y.l/blck);} 22 int main(){//freopen("ddd.in","r",stdin); 23 cin>>n; blck=(int)sqrt(n*1.0); 24 for(int i=1;i<=n;++i) a[i]=rd(); 25 cin>>m; 26 for(int i=1;i<=m;++i) b[i].l=rd(),b[i].r=rd(),b[i].id=i; 27 sort(b+1,b+m+1,cmp); 28 int l=1,r=0,bwl=0; 29 for(int i=1;i<=m;++i){ 30 while(r<b[i].r) bwl+=mdf(a[++r],1); 31 while(r>b[i].r) bwl+=mdf(a[r--],-1); 32 while(l>b[i].l) bwl+=mdf(a[--l],1); 33 while(l<b[i].l) bwl+=mdf(a[l++],-1); 34 ans[b[i].id]=bwl; 35 } 36 for(int i=1;i<=m;++i) printf("%d\n",ans[i]); 37 return 0; 38 }