[BZOJ2120]数颜色
题目大意:
给你一个长度为$n$的正整数序列$A(A_i\leq10^6)$。
给出$m$次操作,操作包含以下两种:
1.将$A_p$上的数修改为$c$;
2.询问区间$[l,r]$中不同数的个数。
思路:
带修莫队。
对于询问区间下标,每$n^\frac{2}{3}$个为一块,共分为$n^\frac{1}{3}$块。
首先对于询问下标按块排序,对于左右端点所属块对应相同的,按时间先后排序。
离线处理询问时,区间的转移就是普通莫队的转移。时间的转移暴力修改。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 inline char getalpha() { 13 register char ch; 14 while(!isalpha(ch=getchar())); 15 return ch; 16 } 17 const int N=10001,MAX=1000001; 18 int tot,a[N],b[N],bel[N],ans[N],cnt[MAX],tmp; 19 struct Query { 20 int l,r,t,id; 21 bool operator < (const Query &another) const { 22 if(bel[l]==bel[another.l]) { 23 if(bel[r]==bel[another.r]) { 24 return t<another.t; 25 } 26 return bel[r]<bel[another.r]; 27 } 28 return bel[l]<bel[another.l]; 29 } 30 }; 31 Query q[N]; 32 struct Modify { 33 int p,c,last; 34 }; 35 Modify mo[N]; 36 inline void ins(const int &x) { 37 if(!cnt[a[x]]++) tmp++; 38 } 39 inline void del(const int &x) { 40 if(!--cnt[a[x]]) tmp--; 41 } 42 int main() { 43 const int n=getint(),m=getint(),block=pow(n,2./3); 44 for(register int i=1;i<=n;i++) { 45 a[i]=b[i]=getint(); 46 bel[i]=i/block; 47 } 48 for(register int i=0;i<m;i++) { 49 const char opt=getalpha(); 50 if(opt=='Q') { 51 const int l=getint(),r=getint(); 52 q[i-tot]=(Query){l,r,tot,i-tot}; 53 } 54 if(opt=='R') { 55 const int p=getint(),c=getint(); 56 mo[++tot]=(Modify){p,c,b[p]}; 57 b[p]=c; 58 } 59 } 60 std::sort(&q[0],&q[m-tot]); 61 for(register int i=0,l=1,r=0,t=0;i<m-tot;i++) { 62 while(r<q[i].r) ins(++r); 63 while(l>q[i].l) ins(--l); 64 while(r>q[i].r) del(r--); 65 while(l<q[i].l) del(l++); 66 while(t<q[i].t) { 67 t++; 68 if(l<=mo[t].p&&mo[t].p<=r) { 69 del(mo[t].p); 70 a[mo[t].p]=mo[t].c; 71 ins(mo[t].p); 72 } else { 73 a[mo[t].p]=mo[t].c; 74 } 75 } 76 while(t>q[i].t) { 77 if(l<=mo[t].p&&mo[t].p<=r) { 78 del(mo[t].p); 79 a[mo[t].p]=mo[t].last; 80 ins(mo[t].p); 81 } else { 82 a[mo[t].p]=mo[t].last; 83 } 84 t--; 85 } 86 ans[q[i].id]=tmp; 87 } 88 for(register int i=0;i<m-tot;i++) { 89 printf("%d\n",ans[i]); 90 } 91 return 0; 92 }