[BZOJ1878][SDOI2009]HH的项链 莫队
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1878
不带修改的莫队,用一个桶记录一下当前区间中每种颜色的数量就可以做到$O(1)$更新了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 int inline readint(){ 7 int Num;char ch; 8 while((ch=getchar())<'0'||ch>'9');Num=ch-'0'; 9 while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0'; 10 return Num; 11 } 12 void outint(int x){ 13 if(x>=10) outint(x/10); 14 putchar(x%10+'0'); 15 } 16 int N,M,blk; 17 int a[50010]; 18 struct Query{ 19 int l,r,p,id; 20 bool operator < (const Query &_)const{ 21 return p!=_.p?p<_.p:r<_.r; 22 } 23 }q[200010]; 24 int Ans[200010],Tans=0; 25 int c[1000010]; 26 void Upd(int x,int d){ 27 if(d==1){ 28 if(!c[a[x]]) Tans++; 29 c[a[x]]++; 30 } 31 else{ 32 if(c[a[x]]==1) Tans--; 33 c[a[x]]--; 34 } 35 } 36 int main(){ 37 N=readint(); 38 blk=ceil(sqrt(N)); 39 for(int i=1;i<=N;i++) a[i]=readint(); 40 M=readint(); 41 for(int i=1;i<=M;i++){ 42 q[i].l=readint(); 43 q[i].r=readint(); 44 q[i].p=(q[i].l-1)/blk+1; 45 q[i].id=i; 46 } 47 sort(q+1,q+1+M); 48 int l=1,r=0; 49 for(int i=1;i<=M;i++){ 50 for(;r<q[i].r;r++) Upd(r+1,1); 51 for(;r>q[i].r;r--) Upd(r,-1); 52 for(;l>q[i].l;l--) Upd(l-1,1); 53 for(;l<q[i].l;l++) Upd(l,-1); 54 Ans[q[i].id]=Tans; 55 } 56 for(int i=1;i<=M;i++){ 57 outint(Ans[i]); 58 putchar('\n'); 59 } 60 return 0; 61 }