BZOJ 2120 数颜色
题解:带修改莫队
左右端点相同按?排序
问题:不会证时间复杂度
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=10009; const int maxc=1000009; const int SIZ=200; int n,m,TT; int a[maxn]; int cntupd; int upp[maxn],upc[maxn]; int c[maxc]; int qx[maxn],qy[maxn],last[maxn],ans[maxn]; int p[maxn]; bool cmp(const int &rhs1,const int &rhs2){ if((qx[rhs1]-1)/SIZ==(qx[rhs2]-1)/SIZ){ return qy[rhs1]<qy[rhs2]; }else{ return qx[rhs1]<qx[rhs2]; } } int main(){ scanf("%d%d",&n,&TT); for(int i=1;i<=n;++i)scanf("%d",&a[i]); int lastupd=0; while(TT--){ char opty=getchar(); int x,y; while(opty!='Q'&&opty!='R')opty=getchar(); scanf("%d%d",&x,&y); if(opty=='Q'){ ++m; qx[m]=x; qy[m]=y; last[m]=lastupd; }else{ ++cntupd; upp[cntupd]=x; upc[cntupd]=y; lastupd=cntupd; } } for(int i=1;i<=m;++i)p[i]=i; sort(p+1,p+1+m,cmp); int l=1,r=0,nowupd=0,nowans=0; for(int i=1;i<=m;++i){ int t=p[i]; int x=qx[t]; int y=qy[t]; while(nowupd<last[t]){ ++nowupd; swap(a[upp[nowupd]],upc[nowupd]); if(upp[nowupd]>=l&&upp[nowupd]<=r){ if(++c[a[upp[nowupd]]]==1)++nowans; if(--c[upc[nowupd]]==0)--nowans; } } while(nowupd>last[t]){ swap(a[upp[nowupd]],upc[nowupd]); if(upp[nowupd]>=l&&upp[nowupd]<=r){ if(++c[a[upp[nowupd]]]==1)++nowans; if(--c[upc[nowupd]]==0)--nowans; } --nowupd; } while(l<x){ if(--c[a[l]]==0)--nowans; ++l; } while(l>x){ --l; if(++c[a[l]]==1)++nowans; } while(r<y){ ++r; if(++c[a[r]]==1)++nowans; } while(r>y){ if(--c[a[r]]==0)--nowans; --r; } ans[t]=nowans; } for(int i=1;i<=m;++i)printf("%d\n",ans[i]); return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!