非旋转 Treap/fhq Treap

· · 个人记录

权值版

宏定义

常量与变量

函数

#define fhqT int
#define pl a[p].l
#define pr a[p].r
struct FHQ_Treap{
    struct Tree{
        int l,r;
        fhqT val;
        int size,dat;
    }a[N],e;
    int tot,root;
    int x,y,z;
    int nc[N];
    FHQ_Treap(){
        root=0;
        tot=N-1;
        e.l=e.r=e.val=e.dat=e.size=0;
        for(int i=1;i<N;i++)
            a[i]=e,nc[i]=i;
    }
    void update(int p){
        a[p].size=a[pl].size+a[pr].size+1;
    }
    int get_new(fhqT val){
        int p=tot--;
        a[p]=e;
        a[p].val=val;
        a[p].dat=rand();
        a[p].size=1;
        return p;
    }
    void split(int p,fhqT val,int &x,int &y){
        if(!p){
            x=y=0;
            return;
        }
        if(a[p].val<=val){
            x=p;
            split(pr,val,pr,y);
        }
        else{
            y=p;
            split(pl,val,x,pl);
        }
        update(p);
    }
    int merge(int p,int q){
        if(!p||!q)
            return p+q;
        if(a[p].dat<a[q].dat){
            a[p].r=merge(a[p].r,q);
            update(p);
            return p;
        }
        a[q].l=merge(p,a[q].l);
        update(q);
        return q;
    }
    void insert(fhqT val){
        split(root,val,x,y);
        root=merge(merge(x,get_new(val)),y);
    }
    void remove(fhqT val){
        split(root,val,x,z);
        split(x,val-1,x,y);
        nc[++tot]=y;
        y=merge(a[y].l,a[y].r);
        root=merge(merge(x,y),z);
    }
    fhqT get_val(int p,int rank){
        if(rank<=a[pl].size)
            return get_val(pl,rank);
        if(rank==a[pl].size+1)
            return a[p].val;
        return get_val(pr,rank-a[pl].size-1);
    }
    int get_rank(fhqT val){
        split(root,val-1,x,y);
        int ans=a[x].size+1;
        root=merge(x,y);
        return ans;
    }
    fhqT get_pre(fhqT val){
        split(root,val-1,x,y);
        fhqT ans=get_val(x,a[x].size);
        root=merge(x,y);
        return ans;
    }
    fhqT get_next(fhqT val){
        split(root,val,x,y);
        fhqT ans=get_val(y,1);
        root=merge(x,y);
        return ans;
    }
    void write(int p){
        if(pl)
            write(pl);
        printf("%d %d %d %d %d %d\n",p,a[p].val,pl,pr,a[pl].val,a[pr].val);
        if(pr)
            write(pr);
    }
}tree;

区间版

以P2042 [NOI2005] 维护数列为标准。

宏定义

常量与变量

函数

#define fhqT int
#define pl a[p].l
#define pr a[p].r
struct FHQ_Treap{
    struct Tree{
        int l,r;
        fhqT val,sum,mx,lmx,rmx;
        int size,dat;
        int tag1,tag2;
    }a[N];
    int tot,root;
    int x,y,z;
    int nc[N];
    fhqT add[N];
    FHQ_Treap(){
        root=0;
        tot=N-1;
        Tree e;
        e.l=e.r=e.val=e.dat=e.size=0;
        e.sum=e.tag1=e.tag2=0;e.lmx=e.rmx=e.mx=0;
        for(int i=0;i<N;i++)
            a[i]=e,nc[i]=i;
    }
    int get_new(fhqT val){
        int p=nc[tot--];
        a[p].sum=a[p].mx=a[p].val=val;
        a[p].dat=rand();
        a[p].size=1;
        a[p].tag1=a[p].tag2=a[p].l=a[p].r=0;
        a[p].lmx=a[p].rmx=max(0,val);
        return p;
    }
    void pushup(int p){
        if(!p)
            return;
        a[p].size=a[pl].size+a[pr].size+1;
        a[p].sum=a[pl].sum+a[p].val+a[pr].sum;
        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);
        a[p].mx=a[pl].rmx+a[p].val+a[pr].lmx;
        if(pl)
            a[p].mx=max(a[p].mx,a[pl].mx);
        if(pr)
            a[p].mx=max(a[p].mx,a[pr].mx);
    }
    void make_same(int p,fhqT c){
        a[p].val=c;
        a[p].sum=a[p].size*c;
        a[p].lmx=a[p].rmx=max(0,a[p].sum);
        a[p].mx=max(c,a[p].sum);
        a[p].tag1=1;
    }
    void reverse(int p){
        swap(pl,pr);
        swap(a[p].lmx,a[p].rmx);
        a[p].tag2^=1;
    }
    void pushdown(int p){
        if(!p)
            return;
        if(a[p].tag1){
            if(pl)
                make_same(pl,a[p].val);
            if(pr)
                make_same(pr,a[p].val);
            a[p].tag1=0;
        }
        if(a[p].tag2){
            if(pl)
                reverse(pl);
            if(pr)
                reverse(pr);
            a[p].tag2=0;
        }
    }
    void split(int p,int rank,int &x,int &y){
        if(!p){
            x=y=0;
            return;
        }
        pushdown(p);
        if(a[pl].size<rank){
            x=p;
            split(pr,rank-a[pl].size-1,pr,y);
        }
        else{
            y=p;
            split(pl,rank,x,pl);
        }
        pushup(p);
    }
    int merge(int p,int q){
        if(!p||!q)
            return p+q;
        if(a[p].dat<a[q].dat){
            pushdown(p);
            a[p].r=merge(a[p].r,q);
            pushup(p);
            return p;
        }
        pushdown(q);
        a[q].l=merge(p,a[q].l);
        pushup(q);
        return q;
    }
    int get_l_to_r(int l,int r){
        split(root,l-1,x,y);
        split(y,r-l+1,y,z);
        return y;
    }
    void merge_back(){
        root=merge(merge(x,y),z);
    }
    int add_num(int l,int r){
        int mid=(l+r)>>1;
        if(l^r)
            return merge(add_num(l,mid),add_num(mid+1,r));
        return get_new(add[l]);
    }
    void insert(int rank,int n){
        split(root,rank,x,y);
        root=merge(merge(x,add_num(1,n)),y);
    }
    void del_num(int p){
        if(!p)
            return;
        nc[++tot]=p;
        del_num(pl);
        del_num(pr);
    }
    void remove(int rank,int n){
        split(root,rank-1,x,y);
        split(y,n,y,z);
        del_num(y);
        root=merge(x,z);
    }
    int get_sum(int p){
        return a[p].sum;
    }
    int get_mx(int p){
        return a[p].mx;
    }
    void write(int p){
        if(!p)
            return;
        pushdown(p);
        write(pl);
        printf("%d %d %d %d %d %d\n",p,a[p].val,pl,pr,a[pl].val,a[pr].val);
        write(pr);
    }
}tree;