Splay

· · 个人记录

## 权值版 ```cpp #define pl a[p].son[0] #define pr a[p].son[1] struct Splay{ int root,tot; int nc[N],INF; struct Tree{ int fa,son[2]; int val; int size,cnt; }a[N],e; Splay(){ root=tot=0; INF=0x7fffffff; e.fa=e.son[0]=e.son[1]=0; e.val=e.size=e.cnt=0; for(int i=1;i<N;i++) nc[i]=i; } int get_type(int p){ return a[a[p].fa].son[1]==p; } void pushup(int p){ a[p].size=a[pl].size+a[pr].size+a[p].cnt; } void connect(int p,int fp,int type){ a[p].fa=fp; a[fp].son[type]=p; } void rotate(int p){ int fp=a[p].fa,type_p=get_type(p); int ffp=a[fp].fa,type_fp=get_type(fp); connect(a[p].son[type_p^1],fp,type_p); connect(fp,p,type_p^1); connect(p,ffp,type_fp); pushup(fp); pushup(p); } void splay(int p,int to){ int fp; while(a[p].fa^to) { fp=a[p].fa; if(a[fp].fa==to) rotate(p); else if(get_type(p)^get_type(fp)) rotate(p),rotate(p); else rotate(fp),rotate(p); } if(!to) root=p; } int get_new(int val,int fp,int type){ int p=nc[++tot]; a[p]=e; a[p].val=val; a[p].size=a[p].cnt=1; connect(p,fp,type); return p; } int Get(int val){ int p=root; while(a[p].val^val&&a[p].son[val>a[p].val]) p=a[p].son[val>a[p].val]; return p; } int get(int val){ int p=Get(val); if(!p) return INF; return a[p].val; } int Pre(int val){ splay(Get(val),0); if(val>a[root].val) return root; int p=a[root].son[0]; if(!p) return 0; while(pr) p=pr; return p; } int Next(int val){ splay(Get(val),0); if(val<a[root].val) return root; int p=a[root].son[1]; if(!p) return 0; while(pl) p=pl; return p; } int Val(int rank){ int p=root; while(1){ if(rank>a[pl].size&&rank<=a[pl].size+a[p].cnt) break; if(rank<=a[pl].size) p=pl; else{ rank-=a[pl].size+a[p].cnt; p=pr; } } splay(p,0); return p; } void insert(int val){ int p=root; if(!tot){ root=get_new(val,0,1); return; } while(1){ a[p].size++; if(val==a[p].val){ a[p].cnt++; break; } if(!a[p].son[val>a[p].val]){ p=get_new(val,p,val>a[p].val); break; } p=a[p].son[val>a[p].val]; } splay(p,0); } void remove(int val){ int p=Get(val); if(a[p].val^val) return; splay(p,0); if(a[p].cnt>1){ a[p].cnt--; a[p].size--; return; } nc[tot--]=p; if(!pl){ a[root=pr].fa=0; return; } int tl=pl,tr=pr; while(a[tl].son[1]) tl=a[tl].son[1]; splay(tl,p); connect(tr,tl,1); connect(tl,0,1); pushup(root=tl); } int get_pre(int val){ int p=Pre(val); if(!p) return -INF; return a[p].val; } int get_next(int val){ int p=Next(val); if(!p) return INF; return a[p].val; } int get_rank(int val){ splay(Next(val-1),0); return a[a[root].son[0]].size+1; } int get_val(int rank){ return a[Val(rank)].val; } void dfs(int p){ if(!p) return; dfs(pl); cout<<p<<" "<<a[p].val<<" "<<pl<<" "<<pr<<endl; dfs(pr); } }tree; ``` ## 区间版 ```cpp #define pl a[p].son[0] #define pr a[p].son[1] struct Splay{ int root,tot; int nc[N],INF; struct Tree{ int fa,son[2]; int val,sum; int mx,lmx,rmx; int tag_re,tag_sa,tag; int size; }a[N],e; int add[N],z[N],t; void connect(int p,int fp,int type){ a[p].fa=fp; a[fp].son[type]=p; } Splay(){ tot=2; INF=0x7fffffff; e.fa=e.son[0]=e.son[1]=0; e.val=e.size=0; e.sum=e.lmx=e.rmx=e.mx=0; e.tag_re=e.tag_sa=e.tag=0; for(int i=1;i<N-2;i++) nc[i]=i+2; a[0].mx=-INF; a[root=1].val=-INF; a[2].val=-INF; connect(2,1,1); } int get_type(int p){ return a[a[p].fa].son[1]==p; } void change_same(int p,int val){ if(!p) return; a[p].tag=1; a[p].val=a[p].tag_sa=val; a[p].sum=val*a[p].size; a[p].lmx=a[p].rmx=max(a[p].sum,0); a[p].mx=max(a[p].sum,val); } void change_rev(int p){ if(a[p].tag) return; swap(pl,pr); swap(a[p].lmx,a[p].rmx); a[p].tag_re^=1; } void pushup(int p){ a[p].size=a[pl].size+a[pr].size+1; a[p].sum=a[pl].sum+a[pr].sum+a[p].val; a[p].mx=max(a[pl].mx,a[pr].mx); a[p].mx=max(a[pl].rmx+a[p].val+a[pr].lmx,a[p].mx); a[p].lmx=max(a[pl].lmx,a[pl].sum+a[p].val+a[pr].lmx); a[p].rmx=max(a[pr].rmx,a[pr].sum+a[p].val+a[pl].rmx); } void pushdown(int p){ if(a[p].tag){ change_same(pl,a[p].tag_sa); change_same(pr,a[p].tag_sa); a[p].tag=0; } if(a[p].tag_re){ change_rev(pl); change_rev(pr); a[p].tag_re=0; } } void rotate(int p){ int fp=a[p].fa,type_p=get_type(p); int ffp=a[fp].fa,type_fp=get_type(fp); connect(a[p].son[type_p^1],fp,type_p); connect(fp,p,type_p^1); connect(p,ffp,type_fp); pushup(fp); pushup(p); } void splay(int p,int to){ int fp; int kp=p; top=0; z[++t]=kp; while(kp) z[++t]=kp=a[kp].fa; t--; while(t) pushdown(z[t--]); while(a[p].fa^to){ fp=a[p].fa; if(a[fp].fa==to) rotate(p); else if(get_type(p)^get_type(fp)) rotate(p),rotate(p); else rotate(fp),rotate(p); } if(!to) root=p; } int New(int val,int fp,int type){ int p=nc[++tot]; a[p]=e; a[p].val=a[p].sum=a[p].mx=val; a[p].size=1; a[p].lmx=a[p].rmx=max(val,0); connect(p,fp,type); return p; } void Del(int p){ if(!p) return; nc[tot--]=p; Del(pl); Del(pr); } int Build(int l,int r,int fp,int fp_id){ int mid=(l+r)>>1; int p=New(add[mid],fp,mid>=fp_id); if(l==r) return p; if(l<mid) Build(l,mid-1,p,mid); if(r>mid) Build(mid+1,r,p,mid); pushup(p); return p; } int Get(int rank){ int p=root; while(1){ pushdown(p); if(rank<=a[pl].size) p=pl; else if(rank==a[pl].size+1) return p; else{ rank-=a[pl].size+1; p=pr; } } } int get(int rank){ return Get(rank+1); } int split(int l,int r){ int x=get(l-1),y=get(r+1); splay(x,0); splay(y,x); return a[y].son[0]; } void insert(int pos,int len){ int rt=Build(1,len,0,0); int x=get(pos),y=get(pos+1); splay(x,0); splay(y,x); connect(rt,y,0); pushup(y); pushup(x); } void remove(int pos,int len){ int p=split(pos,pos+len-1); int fp=a[p].fa; a[fp].son[0]=0; Del(p); pushup(fp); pushup(a[p].fa); } void make_same(int l,int r,int val){ int p=split(l,r); int fp=a[p].fa; change_same(p,val); pushup(fp); pushup(a[fp].fa); } void reverse(int l,int r){ int p=split(l,r); int fp=a[p].fa; change_rev(p); pushup(fp); pushup(a[fp].fa); } int get_sum(int l,int r){ return a[split(l,r)].sum; } int get_max(int l,int r){ return a[split(l,r)].mx; } void dfs(int p){ if(!p) return; dfs(pl); cout<<p<<" "<<a[p].val<<" "<<pl<<" "<<pr<<endl; dfs(pr); } }tree; ```