bzoj 2120 數顏色(帶修改莫隊模板題)
阿新 • • 發佈:2019-02-01
題目:1、 Q L R代表詢問你從第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。 2、 R P Col 把第P支畫筆替換為顏色Col。
思路:帶修改莫隊,不修改時直接對區間維護就行,帶修改時多維護一個時間變數,與不修改的莫隊同樣的思路。
#include<bits/stdc++.h> using namespace std; const int maxn=10005; struct node1{ int l,r,id,t; node1(){} node1(int _l,int _r,int _id,int _t) { l=_l; r=_r; id=_id; t=_t; } }s[maxn]; int block[maxn]; bool cmp1(const node1 &a,const node1 &b) { if(block[a.l]==block[b.l]) { if(a.r==b.r) return a.t<b.t; return a.r<b.r; } return a.l<b.l; } struct node2{ int pos,la,now; node2(){} node2(int _pos,int _la,int _now) { pos=_pos; la=_la; now=_now; } }u[maxn]; int la[maxn]; int a[maxn],n,m,m1,m2; int ans[maxn],c[1000010],sum,l,r,t; void update1(int k,int v) { if(k>=l&&k<=r) { c[a[k]]--; if(c[a[k]]==0) sum--; a[k]=v; c[a[k]]++; if(c[a[k]]==1) sum++; } else a[k]=v; } void update2(int k,int v) { if(c[a[k]]) sum--; c[a[k]]+=v; if(c[a[k]]) sum++; } void Modui() { l=1,r=0;t=0;sum=0; for(int i=1;i<=m1;i++) { while(t<s[i].t) { t++; update1(u[t].pos,u[t].now); } while(t>s[i].t) { update1(u[t].pos,u[t].la); t--; } while(r<s[i].r) { r++; update2(r,1); } while(r>s[i].r) { update2(r,-1); r--; } while(l<s[i].l) { update2(l,-1); l++; } while(l>s[i].l) { l--; update2(l,1); } ans[s[i].id]=sum; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); la[i]=a[i]; } m1=m2=0; for(int i=1;i<=m;i++) { char ch[3]; int x,y; scanf("%s%d%d",ch,&x,&y); if(ch[0]=='Q') { m1++; s[m1]=node1(x,y,m1,m2); } else { u[++m2]=node2(x,la[x],y); la[x]=y; } } int o=sqrt(n); for(int i=1;i<=n;i++) block[i]=i/o; sort(s+1,s+m1+1,cmp1); Modui(); for(int i=1;i<=m1;i++) printf("%d\n",ans[i]); return 0; }