块大小n ^2/3 ,时间复杂度 n^5/3
左端点-右端点-时间
#include<bits/stdc++.h> using namespace std; const int maxn=10004; int n,m,tot=0,tot1=0,bel[maxn],blo,vis[1000004],col[maxn],S[maxn],ans[maxn],num=0; //vis记录颜色出现多少次,num记录不同颜色个数 int l=0,r=0,o=0; struct node{ int id,last,l,r; }a[maxn],b[maxn]; bool operator < (const node &x,const node &y){ if(bel[x.l]==bel[y.l]){ if(bel[x.r]==bel[y.r]) return x.last<y.last; return bel[x.r]<bel[y.r]; } return bel[x.l]<bel[y.l]; } inline void change1(int x){//时间后移 b[x].l from col[b[x].l] to b[x].r if(col[b[x].l]!=b[x].r){ if(b[x].l<=r&&b[x].l>=l){ vis[b[x].r]++; if(vis[b[x].r]==1) num++; vis[col[b[x].l]]--; if(!vis[col[b[x].l]]) num--; } col[b[x].l]=b[x].r; } } inline void change(int x){//时间倒流 b[x].l from col[b[x].l] to b[x].last if(col[b[x].l]!=b[x].last){ if(b[x].l<=r&&b[x].l>=l){ vis[b[x].last]++; if(vis[b[x].last]==1) num++; vis[col[b[x].l]]--; if(!vis[col[b[x].l]]) num--; } col[b[x].l]=b[x].last; } } inline void add(int x){ vis[col[x]]++; if(vis[col[x]]==1) num++; } inline void del(int x){ vis[col[x]]--; if(!vis[col[x]]) num--; } int main(){ scanf("%d%d",&n,&m); blo=pow(n,2.0/3); for(int i=1;i<=n;i++){ bel[i]=(i-1)/blo+1; scanf("%d",&col[i]); S[i]=col[i]; } for(int i=1;i<=m;i++){ char s[5]; scanf("%s",s); if(s[0]=='Q'){ tot++; scanf("%d%d",&a[tot].l,&a[tot].r); a[tot].id=tot; a[tot].last=tot1; }else{ tot1++;//l位置,r元素值 scanf("%d%d",&b[tot1].l,&b[tot1].r); b[tot1].last=S[b[tot1].l];//为了删除 ,记录上一个修改的颜色信息 S[b[tot1].l]=b[tot1].r; } } sort(a+1,a+tot+1); for(int i=1;i<=tot;i++){ while(o<a[i].last) change1(++o);//时间后移 while(o>a[i].last) change(o--);//时间倒流 while(r<a[i].r) add(++r); while(l>a[i].l) add(--l); while(l<a[i].l) del(l++); while(r>a[i].r) del(r--); ans[a[i].id]=num; } for(int i=1;i<=tot;i++){ printf("%d\n",ans[i]); } }