非旋treap模板

非旋treap模板

struct Treap{
    int ls[MAXN],rs[MAXN],siz[MAXN],rd[MAXN]int val[MAXN];
    bool flag[MAXN];
    int root,cnt,ltr,mtr,rtr;
    Treap(){cnt=0;srand(996);}
    int random(){return rand()<<8|rand();}
    void up(int x){siz[x]=siz[ls[x]]+siz[rs[x]]+1;}
    void dn(int x){flag[x]^=1;swap(ls[x],rs[x]);flag[ls[x]]^=1;flag[rs[x]]^=1;}
    void split(int r,int v,int&x,int&y){
        if(!r){x=y=0;return;}
        if(val[r]<=v)x=r,split(rs[r],v,rs[r],y);
        else y=r,split(ls[r],v,x,ls[r]);
        up(r);
    }
    /*序列
    void split(int r,int k,int&x,int&y){
        if(!r){y=x=0;return;}
        if(flag[r])dn(r);
        if(siz[ls[r]]+1<=k)x=r,split(rs[r],k-siz[ls[r]]-1,rs[r],y);
        else y=r,split(ls[r],k,x,ls[r]);
        up(r);
    }*/
    int merge(int x,int y){
        if(!x||!y)return x+y;
        //if(flag[x])dn(x);
        //if(flag[y])dn(y);
        if(rd[x]<rd[y])return rs[x]=merge(rs[x],y),up(x),x;
        else return ls[y]=merge(x,ls[y]),up(y),y;
    }
    int newnode(int v){
        siz[++cnt]=1;
        val[cnt]=v,rd[cnt]=random();
        return cnt;
    }
    void insert(int v){
        split(root,v,ltr,rtr);
        root=merge(merge(ltr,newnode(v)),rtr);
    }
    void del(int v){
        split(root,v,ltr,rtr);
        split(ltr,v-1,ltr,mtr);
        mtr=merge(ls[mtr],rs[mtr]);//可能有多个相同的值插入
        root=merge(merge(ltr,mtr),rtr);
    }
    int val_kth(int v){
        split(root,v-1,ltr,rtr);
        int res=siz[ltr]+1;
        root=merge(ltr,rtr);
        return res;
    }
    int kth_val(int r,int k){
        if(k<=siz[ls[r]])return kth_val(ls[r],k);
        if(k==siz[ls[r]]+1)return val[r];
        return kth_val(rs[r],k-siz[ls[r]]-1);
    }
    int val_pre(int v){
        split(root,v-1,ltr,rtr);
        int res=kth_val(ltr,siz[ltr]);
        merge(ltr,rtr);
        return res;
    }
    int val_nxt(int v){
        split(root,v,ltr,rtr);
        int res=kth_val(rtr,1);
        merge(ltr,rtr);
        return res;
    }
    //区间翻转
    void reverse(int l,int r){
        split(root,r,mtr,rtr);
        split(mtr,l-1,ltr,mtr);
        cout<<siz[mtr]<<endl;
        flag[mtr]^=1;
        root=merge(merge(ltr,mtr),rtr);
    }
    void print(int r){//中序遍历结果
        if(!r)return;
        if(flag[r])dn(r);
        print(ls[r]);
        printf("%d ",val[r]);
        print(rs[r]);
    }
}treap;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值