大力分块艹过去了
直接分块+bitset,离散化后记录每块内每种颜色出现的次数,这样一次修改是$O(1)$的(不算离散化的话)。然而查询时因为要合并块,所以复杂度是整块长度之和这个级别的的(虽然有个bitset的$\frac{1}{32}$),直接把块大小$siz$设成$sqrt(n)$做大概会比较慢。
为了提高效率,这里可以适当加大块的大小,这样块合并会变少而零散区间的统计会变多,在这个题效率会更高一点(我一开始弄了一个$n^{\frac{3}{5}}$的块大小(块最大的时候大概是660)卡过去了,最慢的点跑了600+ms,后来又试了试然后还加了个“输出优化(不知道有没有用啊=。=)”,把块大小搞成$n^{\frac{3}{4}}$跑的更快了些(块最大的时候大概是3400),就是上面说的300ms+)
1 // luogu-judger-enable-o2 2 #include<cmath> 3 #include<cstdio> 4 #include<cctype> 5 #include<bitset> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 const int N=50005,M=100005,Sq=20; 10 struct a 11 { 12 int typ; 13 int ll,rr; 14 }q[N]; 15 int n,m,t1,t2,t3,t4,sqr,cnt,xnt,len; 16 int pts[Sq][2],app[Sq][M]; 17 int a[N],blo[N],uni[2*N]; 18 bitset<M> sta[Sq],qry; 19 char rd[5]; 20 inline int read() 21 { 22 int ret=0; 23 char ch=getchar(); 24 while(!isdigit(ch)) 25 ch=getchar(); 26 while(isdigit(ch)) 27 ret=(ret<<1)+(ret<<3)+(ch^48),ch=getchar(); 28 return ret; 29 } 30 inline void write(int x) 31 { 32 if(x>9) write(x/10); 33 putchar(x%10+48); 34 } 35 int main() 36 { 37 register int i,j; 38 n=read(),m=read(),xnt=n; 39 sqr=pow(n,0.75),pts[cnt=1][0]=1; 40 for(i=1;i<=n;i++) 41 { 42 a[i]=read(),uni[i]=a[i]; 43 blo[i]=(i-1)/sqr+1; 44 if(i%sqr==0) 45 { 46 pts[cnt++][1]=i; 47 pts[cnt][0]=i+1; 48 } 49 } 50 pts[cnt][1]=n; 51 for(i=1;i<=m;i++) 52 { 53 scanf("%s",rd),t1=read(),t2=read(); 54 q[i].ll=t1,q[i].rr=t2,q[i].typ=(rd[0]=='R'); 55 if(q[i].typ) uni[++xnt]=t2; 56 } 57 sort(uni+1,uni+1+xnt),len=unique(uni+1,uni+1+xnt)-uni-1; 58 for(i=1;i<=n;i++) 59 { 60 a[i]=lower_bound(uni+1,uni+1+len,a[i])-uni; 61 if(++app[blo[i]][a[i]]==1) sta[blo[i]][a[i]]=true; 62 } 63 for(i=1;i<=m;i++) 64 { 65 t1=q[i].ll,t2=q[i].rr; 66 if(q[i].typ) 67 { 68 int bel=blo[t1],newc=lower_bound(uni+1,uni+1+len,t2)-uni; 69 if(!(--app[bel][a[t1]])) sta[bel][a[t1]]=false; 70 if(++app[bel][newc]==1) sta[bel][newc]=true; a[t1]=newc; 71 } 72 else 73 { 74 qry.reset(),t3=blo[t1],t4=blo[t2]; 75 if(t3!=t4) 76 { 77 for(j=t1;j<=pts[t3][1];j++) qry[a[j]]=true; 78 for(j=pts[t4][0];j<=t2;j++) qry[a[j]]=true; 79 for(j=t3+1;j<=t4-1;j++) qry|=sta[j]; 80 } 81 else for(j=t1;j<=t2;j++) qry[a[j]]=true; 82 write((int)qry.count()),puts(""); 83 } 84 } 85 return 0; 86 }