BZOJ3595 : [Scoi2014]方伯伯的Oj
2014-05-18 23:20
323 查看
由于n很大,有2e8,所以不能直接用splay来维护排名
把splay修改一下
每个节点维护一个区间[l,r],表示编号在[l,r]之间的所有点都在这里
需要支持一个takeout操作:
把编号为k的玩家分离出来,成为一个独立的点
先找到它所在的大点x
splay(x)
然后分裂成1-3个节点
关于如何查找编号为k的玩家在splay中哪个节点
可以开一棵动态开节点的线段树来维护
每次分裂实质就是区间赋值,打标记即可
时间复杂度$O(m\log n)$
写起来真是神清气爽…
把splay修改一下
每个节点维护一个区间[l,r],表示编号在[l,r]之间的所有点都在这里
需要支持一个takeout操作:
把编号为k的玩家分离出来,成为一个独立的点
先找到它所在的大点x
splay(x)
然后分裂成1-3个节点
关于如何查找编号为k的玩家在splay中哪个节点
可以开一棵动态开节点的线段树来维护
每次分裂实质就是区间赋值,打标记即可
时间复杂度$O(m\log n)$
写起来真是神清气爽…
#include<cstdio> #define N 300010 #define M 9000000 const int R=200000000; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} int ans; struct Segmenttree{ int tot,l[M],r[M],tag[M],val[M]; inline void make1(int x,int a,int b,int p){ if(!x)return; if(a==b)val[x]=p;else tag[x]=p; } inline void pb(int x,int a,int b){ if(tag[x]){ int mid=(a+b)>>1; if(!l[x])l[x]=++tot; if(!r[x])r[x]=++tot; make1(l[x],a,mid,tag[x]); make1(r[x],mid+1,b,tag[x]); tag[x]=0; } } void change(int x,int a,int b,int c,int d,int p){ if(c<=a&&b<=d){ make1(x,a,b,p); return; } int mid=(a+b)>>1; pb(x,a,b); if(c<=mid){ if(!l[x])l[x]=++tot; change(l[x],a,mid,c,d,p); } if(d>mid){ if(!r[x])r[x]=++tot; change(r[x],mid+1,b,c,d,p); } } int ask(int x,int a,int b,int c){ if(a==b)return val[x]; int mid=(a+b)>>1; pb(x,a,b); return c<=mid?ask(l[x],a,mid,c):ask(r[x],mid+1,b,c); } inline void init(){ tot=1; make1(1,1,R,1); } }S; int tot,root,f ,son [2],l ,r ,sum ; inline void init(int n){ tot=root=l[1]=1;r[1]=n; } inline void up(int x){sum[x]=sum[son[x][0]]+sum[son[x][1]]+r[x]-l[x]+1;} inline void setson(int x,int w,int y){son[x][w]=y;if(y)f[y]=x;} inline void rotate(int x){ int y=f[x],w=son[y][1]==x; son[y][w]=son[x][!w]; if(son[x][!w])f[son[x][!w]]=y; if(f[y]){ int z=f[y]; if(son[z][0]==y)son[z][0]=x; if(son[z][1]==y)son[z][1]=x; } f[x]=f[y];f[y]=x;son[x][!w]=y;up(y); } inline void splay(int x){ while(f[x]){ int y=f[x]; if(f[y]){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);} rotate(x); } up(root=x); } inline int kth(int k){ int x=root,nl,nr; while(1){ nl=sum[son[x][0]]+1;nr=nl+r[x]-l[x]; if(nl<=k&&k<=nr)return k-nl+l[x]; if(k<nl)x=son[x][0]; else k-=nr,x=son[x][1]; } } inline int takeout(int k){//将编号为k的点分离成单点 int x=S.ask(1,1,R,k); splay(x); int tl=l[x],tr=r[x],sl=son[x][0],sr=son[x][1]; l[x]=r[x]=k; if(k!=tl){ int y=++tot; l[y]=tl;r[y]=k-1; setson(y,0,sl); up(y); S.change(1,1,R,tl,k-1,y); setson(x,0,y); }else setson(x,0,sl); if(k!=tr){ int y=++tot; l[y]=k+1;r[y]=tr; setson(y,1,sr); up(y); S.change(1,1,R,k+1,tr,y); setson(x,1,y); }else setson(x,1,sr); up(x); ans=sum[son[x][0]]+1; return x; } inline void top(int k){//把编号为k的点放在首位 int x=takeout(k),a=son[x][0],b=son[x][1],i; if(b){ f[b]=0; i=b; while(son[i][0])i=son[i][0]; splay(i); setson(i,0,a); up(i); }else root=a; son[x][0]=0; setson(x,1,root); up(root=x); } inline void bottom(int k){//把编号为k的点放在末尾 int x=takeout(k),a=son[x][0],b=son[x][1],i; if(b){ f[b]=0; i=b; while(son[i][0])i=son[i][0]; splay(i); setson(i,0,a); up(i); }else root=a; son[x][1]=0; setson(x,0,root); up(root=x); } inline void change(int k,int p){//把编号为k的点的编号改为p int x=takeout(k); l[x]=r[x]=p; S.change(1,1,R,p,p,x); } int n,m,k,x,y; int main(){ read(n);read(m); init(n); S.init(); while(m--){ read(k);read(x);x-=ans; if(k==1){ read(y);y-=ans; change(x,y); printf("%d\n",ans); } if(k==2)top(x),printf("%d\n",ans); if(k==3)bottom(x),printf("%d\n",ans); if(k==4)printf("%d\n",ans=kth(x)); } return 0; }
相关文章推荐
- bzoj3595: [Scoi2014]方伯伯的Oj【splay+map】
- NKOJ 4340 (SCOI 2014)方伯伯的OJ (Splay+map+set)
- 【Treap】[Scoi2014] bzoj3595 方伯伯的Oj
- BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap
- SCOI2014 方伯伯的OJ onlinejudge
- 省选专练[SCOI2014]方伯伯的OJ
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
- 【bzoj 3595】: [Scoi2014]方伯伯的Oj
- [SCOI2014]方伯伯的OJ (非旋treap不可做! (╯‵□′)╯︵┻━┻)
- [BZOJ3595][SCOI2014]方伯伯的OJ(平衡树)
- 【双Treap】[Scoi2014] bzoj3595 方伯伯的Oj
- 【bzoj3594】 SCOI2014方伯伯的玉米田 dp+二维树状数组优化
- bzoj3597 [Scoi2014]方伯伯运椰子
- bzoj3597[Scoi2014]方伯伯运椰子 01分数规划+spfa判负环
- [bzoj3594][Scoi2014]方伯伯的玉米田 树状数组优化dp
- 【bzoj 3598】: [Scoi2014]方伯伯的商场之旅
- BZOJ3594[Scoi2014] 方伯伯的玉米田 解题报告【二维树状数组优化DP】
- bzoj3594 [Scoi2014]方伯伯的玉米田
- BZOJ 3597 [Scoi2014]方伯伯运椰子
- bzoj3594[Scoi2014]方伯伯的玉米田