Splay

Splay\text{Splay} 的宏定义、常量与变量、函数的内容与非旋转 Treap/fhq Treap 中的相关内容大致相同,这里不再多做解释其实是不想写

权值版

#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;

区间版

#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;
posted @ 2022-02-18 13:34  luckydrawbox  阅读(6)  评论(0)    收藏  举报  来源