[国家集训队][bzoj2120] 数颜色 [带修改莫队]
题面:
思路:
这道题和SDOI2009的HH的项链很像,只是多了一个修改
模板套上去呀
莫队学习请戳这里:莫队
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 inline int read(){ 8 int re=0,flag=1;char ch=getchar(); 9 while(ch>'9'||ch<'0'){ 10 if(ch=='-') flag=-1; 11 ch=getchar(); 12 } 13 while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar(); 14 return re*flag; 15 } 16 int n,m,cnt[1000010],tot=0,x[50010],cur[50010]; 17 int curl,curr,curc,block,ans[200010],cntq,cntc; 18 struct query{ 19 int l,r,i,ch; 20 }a[200010]; 21 struct ch{ 22 int pos,to,from; 23 }c[200010]; 24 bool cmp(query l,query r){ 25 if(l.l/block!=r.l/block) return (l.l/block)<(r.l/block); 26 else{ 27 if(l.r!=r.r) return l.r<r.r; 28 else return l.ch<r.ch; 29 } 30 } 31 void add(int i){ 32 cnt[x[i]]++;if(cnt[x[i]]==1) tot++; 33 //cout<<"add "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<" "<<tot<<"\n"; 34 } 35 void erase(int i){ 36 cnt[x[i]]--;if(!cnt[x[i]]) tot--; 37 //cout<<"erase "<<i<<" "<<x[i]<<" "<<cnt[x[i]]<<" "<<tot<<"\n"; 38 } 39 void change(int l,int r,int i){ 40 //cout<<"***change "<<l<<" "<<r<<" "<<i<<" "<<x[c[i].pos]<<"\n"; 41 if(l<=c[i].pos&&c[i].pos<=r) erase(c[i].pos); 42 x[c[i].pos]=c[i].to; 43 if(l<=c[i].pos&&c[i].pos<=r) add(c[i].pos); 44 } 45 void back(int l,int r,int i){ 46 //cout<<"***back "<<l<<" "<<r<<" "<<i<<"\n"; 47 if(l<=c[i].pos&&c[i].pos<=r) erase(c[i].pos); 48 x[c[i].pos]=c[i].from; 49 if(l<=c[i].pos&&c[i].pos<=r) add(c[i].pos); 50 } 51 int main(){ 52 // freopen("testdata.in","r",stdin); 53 int i,t1,t2;char s[10]; 54 n=read();m=read(); 55 for(i=1;i<=n;i++) x[i]=cur[i]=read(); 56 for(i=1;i<=m;i++){ 57 scanf("%s",s);t1=read();t2=read(); 58 if(s[0]=='Q') 59 a[++cntq].l=t1,a[cntq].r=t2,a[cntq].i=cntq,a[cntq].ch=cntc; 60 else 61 c[++cntc].pos=t1,c[cntc].from=cur[t1],cur[t1]=c[cntc].to=t2; 62 } 63 block=sqrt(n); 64 sort(a+1,a+cntq+1,cmp); 65 66 curl=a[1].l;curr=a[1].r; 67 for(i=a[1].l;i<=a[1].r;i++) add(i); 68 while(curc<a[1].ch) change(a[1].l,a[1].r,++curc); 69 ans[a[1].i]=tot; 70 71 for(i=2;i<=m;i++){ 72 while(curl<a[i].l) erase(curl++); 73 while(curl>a[i].l) add(--curl); 74 while(curr<a[i].r) add(++curr); 75 while(curr>a[i].r) erase(curr--); 76 while(curc<a[i].ch) change(a[i].l,a[i].r,++curc); 77 while(curc>a[i].ch) back(a[i].l,a[i].r,curc--); 78 ans[a[i].i]=tot; 79 //cout<<"now "<<curl<<" "<<curr<<"\n"; 80 } 81 for(i=1;i<=cntq;i++) printf("%d\n",ans[i]); 82 } 83