bzoj 2120: 数颜色 线段树套平衡树
/************************************************************** Problem: 2120 User: wangyucheng Language: C++ Result: Accepted Time:1748 ms Memory:50220 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<set> using namespace std; #define N 13000 #define M 1050000 #define inf 0x3fffffff int ch[M][2],pre[M],siz[M],val[M],ne[N]; int col[N]; int rt[N*4],L[N*4],R[N*4]; int bb[M]; set<int> jj[1000010]; void up(int x){ siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } void rot(int x){ int y=pre[x],z=pre[y]; int k=ch[y][0]==x; pre[ch[y][!k]=ch[x][k]]=y; pre[ch[x][k]=y]=x; pre[x]=z; if(!z)rt[bb[y]]=x; else ch[z][ch[z][1]==y]=x; up(y); } void splay(int x,int f){ int y,z; for(;pre[x]!=f;){ y=pre[x],z=pre[y]; if(z==f)rot(x); else if((ch[y][1]==x)==(ch[z][1]==y))rot(y),rot(x); else rot(x),rot(x); } up(x); } int n,m; int nod; int mk[N]; void select(int p,int k,int f){ int x=rt[p]; while(siz[ch[x][0]]+1!=k){ if(siz[ch[x][0]]>=k)x=ch[x][0]; else k-=siz[ch[x][0]]+1,x=ch[x][1]; } splay(x,f); } int Bui(int l,int r,int p){ if(l>r)return 0; int k=++nod; bb[k]=p; int mid=l+r>>1; val[k]=mk[mid]; pre[ch[k][0]=Bui(l,mid-1,p)]=k; pre[ch[k][1]=Bui(mid+1,r,p)]=k; up(k); return k; } void build(int l,int r,int k){ for(int i=2;i<=r-l+2;i++)mk[i]=ne[l+i-2]; mk[1]=-inf; mk[r-l+3]=inf; L[k]=l,R[k]=r; sort(mk+1,mk+r-l+4); rt[k]=Bui(1,r-l+3,k); if(l==r)return; int mid=l+r>>1; build(l,mid,k<<1); build(mid+1,r,k<<1|1); } int find(int p,int vv){ int x=rt[p]; int ma,as=-1; while(x){ if(val[x]<=vv){ if(as==-1||val[x]>ma)as=x,ma=val[x]; x=ch[x][1]; }else x=ch[x][0]; } return as; } int count(int p,int vv){ int as=find(p,vv); splay(as,0); return siz[ch[as][0]]; } void dele(int p,int vv){ int x=find(p,vv); splay(x,0); int k=siz[ch[x][0]]+1; select(p,k-1,0); select(p,k+1,rt[p]); ch[ch[rt[p]][1]][0]=0; splay(ch[rt[p]][1],0); } void ins(int p,int vv){ int x=rt[p],k; while(1){ k=vv>val[x]; if(!ch[x][k]){ pre[ch[x][k]=++nod]=x; val[nod]=vv; bb[nod]=p; splay(nod,0); break; } x=ch[x][k]; } } void change(int l,int k,int vv){ dele(k,ne[l]); ins(k,vv); if(L[k]==R[k])return; if(R[k<<1]>=l)change(l,k<<1,vv); else change(l,k<<1|1,vv); } int ans; void ask(int l,int r,int k,int vv){ if(L[k]>=l&&R[k]<=r){ans+=count(k,vv);return;} if(L[k<<1]<=r&&R[k<<1]>=l)ask(l,r,k<<1,vv); if(L[k<<1|1]<=r&&R[k<<1|1]>=l)ask(l,r,k<<1|1,vv); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&col[i]),jj[col[i]].insert(i); for(int i=1;i<=n;i++){ int u=col[i]; set<int>::iterator it=jj[u].upper_bound(i); if(it==jj[u].end())ne[i]=n+i; else ne[i]=*it; } build(1,n,1); for(int i=1;i<=m;i++){ char a; int b,c; scanf(" %c%d%d",&a,&b,&c); if(a=='R'){ set<int>::iterator it=jj[col[b]].find(b),it2,it3; it3=it; it3++; if(it!=jj[col[b]].begin()){ it2=it; it2--; if(it3==jj[col[b]].end())change(*it2,1,*it2+n),ne[*it2]=*it2+n; else change(*it2,1,*it3),ne[*it2]=*it3; } jj[col[b]].erase(it); jj[c].insert(b); it=jj[c].find(b); it2=jj[c].upper_bound(b); if(it2!=jj[c].end())change(b,1,*it2),ne[b]=*it2; else change(b,1,b+n),ne[b]=b+n; it3=it; if(it!=jj[c].begin()){ it3--; change(*it3,1,b); ne[*it3]=b; } col[b]=c; }else{ ans=0; ask(b,c,1,c); printf("%d\n",c-b+1-ans); } } }