首页 > 代码库 > bzoj 2120: 数颜色 线段树套平衡树
bzoj 2120: 数颜色 线段树套平衡树
/************************************************************** Problem: 2120 User: wangyucheng Language: C++ Result: Time_Limit_Exceed****************************************************************/ #include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<set>using namespace std;#define N 13000#define M 1050000#define inf 0x3fffffffint 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; 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); } }}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。