Splay
luckydrawbox
·
·
个人记录
## 权值版
```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;
```