「算法笔记」FHQ-Treap

参考了各博文,直接放出来不太好(¿),所以请右转→https://www.cnblogs.com/mytqwqq/p/15057231.html qwq

P3369 【模板】普通平衡树

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,op,x;
struct Treap{
    int rt,tot,lc[N],rc[N],val[N],sz[N],rnd[N];
    void upd(int x){
        sz[x]=sz[lc[x]]+sz[rc[x]]+1;
    } 
    int getnew(int k){
        val[++tot]=k,rnd[tot]=rand(),sz[tot]=1;
        return tot;
    }
    void split(int p,int &x,int &y,int k){
        if(!p){x=y=0;return ;}
        if(val[p]<=k) x=p,split(rc[p],rc[p],y,k);
        else y=p,split(lc[p],x,lc[p],k);
        upd(p);
    }
    int merge(int x,int y){    //前提:x 的权值全部 < y 的权值
        if(!x||!y) return x+y;
        if(rnd[x]<rnd[y]){rc[x]=merge(rc[x],y),upd(x);return x;}
        else lc[y]=merge(x,lc[y]),upd(y);
        return y;
    } 
    void insert(int k){
        int x=0,y=0;
        split(rt,x,y,k),rt=merge(merge(x,getnew(k)),y); 
    }
    void erase(int k){
        int x=0,y=0,z=0;
        split(rt,x,z,k),split(x,x,y,k-1);
        rt=merge(merge(x,merge(lc[y],rc[y])),z);
    }
    int rank(int k){
        int x=0,y=0,ans;
        split(rt,x,y,k-1),ans=sz[x]+1,rt=merge(x,y);
        return ans;
    }
    int kth(int rt,int k){
        if(!rt) return 0;
        if(sz[lc[rt]]+1==k) return rt;
        if(sz[lc[rt]]+1>k) return kth(lc[rt],k);
        return kth(rc[rt],k-sz[lc[rt]]-1);
    }
    int pre(int k){
        int x=0,y=0,ans;
        split(rt,x,y,k-1),ans=kth(x,sz[x]),rt=merge(x,y);
        return ans;
    }
    int nxt(int k){
        int x=0,y=0,ans;
        split(rt,x,y,k),ans=kth(y,1),rt=merge(x,y);
        return ans;
    }
}T;
signed main(){
    srand(time(0));
    scanf("%d",&n);
    while(n--){
        scanf("%d%d",&op,&x);
        if(op==1) T.insert(x);
        else if(op==2) T.erase(x);
        else if(op==3) printf("%d\n",T.rank(x));
        else if(op==4) printf("%d\n",T.val[T.kth(T.rt,x)]); 
        else if(op==5) printf("%d\n",T.val[T.pre(x)]);
        else printf("%d\n",T.val[T.nxt(x)]);
    }
    return 0;
}

P3391 【模板】文艺平衡树

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,l,r;
struct Treap{
    int rt,tot,lc[N],rc[N],val[N],sz[N],rnd[N],rev[N];
    void pushup(int x){
        sz[x]=sz[lc[x]]+sz[rc[x]]+1;
    } 
    void pushdown(int x){
        if(!rev[x]) return ;
        swap(lc[x],rc[x]),rev[lc[x]]^=1,rev[rc[x]]^=1;
        rev[x]=0;
    }
    int getnew(int k){
        val[++tot]=k,rnd[tot]=rand(),sz[tot]=1;
        return tot;
    }
    void split(int p,int &x,int &y,int k){    //按子树大小分裂
        if(!p){x=y=0;return ;}
        pushdown(p);
        if(sz[lc[p]]+1<=k) x=p,split(rc[p],rc[p],y,k-sz[lc[p]]-1);
        else y=p,split(lc[p],x,lc[p],k);
        pushup(p);
    }
    int merge(int x,int y){
        if(!x||!y) return x+y;
        if(rnd[x]<rnd[y]){
            pushdown(x),rc[x]=merge(rc[x],y),pushup(x);
            return x;
        }
        else pushdown(y),lc[y]=merge(x,lc[y]),pushup(y);
        return y;
    } 
}T;
void print(int x){
    T.pushdown(x);
    if(T.lc[x]) print(T.lc[x]);
    printf("%d ",T.val[x]);
    if(T.rc[x]) print(T.rc[x]);
}
signed main(){
    srand(time(0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        T.rt=T.merge(T.rt,T.getnew(i));
    while(m--){
        scanf("%d%d",&l,&r);
        int x=0,y=0,z=0;
        T.split(T.rt,x,y,l-1),T.split(y,y,z,r-l+1);
        T.rev[y]^=1,T.rt=T.merge(x,T.merge(y,z));
    }
    print(T.rt);
    return 0;
}

 

posted @ 2021-07-25 11:13  maoyiting  阅读(167)  评论(0编辑  收藏  举报