zoukankan      html  css  js  c++  java
  • 非旋treap

    不旋转,基于split和merge操作的treap

    又是三个模板

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=100007;
    typedef long long LL;
    using namespace std;
    int T,rt;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    int n,v[N],hr[N],l[N],r[N],sz[N],tot;
    #define lc l[x]
    #define rc r[x]
    void update(int x) {sz[x]=sz[lc]+sz[rc]+1;}
    
    int merge(int x,int y) {
        if(!(x*y)) return x^y;
        if(hr[x]<hr[y]) rc=merge(rc,y);
        else {
            swap(x,y);
            lc=merge(y,lc);
        }
        update(x);
        return x; 
    }
    
    #define pr pair<int,int>
    #define se second
    #define fi first
    pr split(int x,int k) {
        if(!x) return make_pair(0,0);
        pr p;
        if(sz[lc]>=k) {
            p=split(lc,k);
            lc=p.se; p.se=x;
        }
        else {
            p=split(rc,k-sz[lc]-1);
            rc=p.fi; p.fi=x;  
        }
        update(x);
        return p;
    }
    
    int cre(int y) {
        int x=++tot;
        hr[x]=rand();
        v[x]=y;
        sz[x]=1;
        return x;
    }
    
    int rank(int y) {
        int res=1;
        for(int x=rt;x;) {
            if(v[x]<y) res+=(sz[lc]+1),x=rc;
            else x=lc;
        }
        return res;
    }
    
    int kth(int k) {
        int res=-1;
        for(int x=rt;x;) {
            if(sz[lc]+1==k) return v[x];
            if(sz[lc]+1>k) x=lc;
            else k-=(sz[lc]+1),x=rc;
        }
    }
    
    int pre(int y) {
        int res=-1;
        for(int x=rt;x;) {
            if(v[x]<y) res=v[x],x=rc;
            else x=lc;
        }
        return res;
    }
    
    int nxt(int y) {
        int res=-1;
        for(int x=rt;x;) {
            if(v[x]>y) res=v[x],x=lc;
            else x=rc;    
        }
        return res;
    }
    
    void insert(int x,int y) {
        int z=cre(y);
        int k=rank(y);
        pr p=split(x,k-1);
        rt=merge(p.fi,z);
        rt=merge(rt,p.se);
    }
    
    void del(int x,int y) {
        int k=rank(y);
        pr p=split(x,k-1);
        pr q=split(p.se,1);
        rt=merge(p.fi,q.se);
    }
    
    int main() {
        srand(time(0));
        read(T);
        while(T--) {
            int o,x;
            read(o); read(x);
            switch(o) {
                case 1:insert(rt,x);break;
                case 2:del(rt,x);break;
                case 3:printf("%d
    ",rank(x));break;
                case 4:printf("%d
    ",kth(x));break;
                case 5:printf("%d
    ",pre(x));break;
                case 6:printf("%d
    ",nxt(x));break;
            }
        }
        return 0;
    }
    普通平衡树
    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=100007;
    typedef long long LL;
    using namespace std;
    int rt,n,m,tot,ch[N][2],hr[N],sz[N],flip[N];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    #define lc ch[x][0]
    #define rc ch[x][1]
    void update(int x) {sz[x]=sz[lc]+sz[rc]+1;}
    
    int build(int l,int r) {
        if(l>r) return 0;
        int mid=((l+r)>>1);
        int tplc=build(l,mid-1);
        int x=++tot; 
        hr[x]=rand();
        lc=tplc;
        rc=build(mid+1,r);
        update(x);
        return x;
    }
    
    void down(int x) {
        if(!flip[x]) return;
        swap(lc,rc);
        if(lc) flip[lc]^=1;
        if(rc) flip[rc]^=1;
        flip[x]^=1;
    }
    
    #define pr pair<int,int>
    #define fi first
    #define se second
    pr split(int x,int k) {
        if(!x) return make_pair(0,0);
        pr p;
        down(x);
        if(sz[lc]>=k) {
            p=split(lc,k);
            lc=p.se; p.se=x;
        }
        else {
            p=split(rc,k-sz[lc]-1);
            rc=p.fi; p.fi=x;
        }
        update(x);
        return p;
    }
    
    int merge(int x,int y) {
        if(!(x*y)) return x^y;
        if(hr[x]<hr[y]) {
            down(x);
            rc=merge(rc,y);
        }
        else {
            swap(x,y);
            down(x);
            lc=merge(y,lc);
        }
        update(x);
        return x;
    } 
    
    void rever(int l,int r) {
        pr p=split(rt,l-1);
        pr q=split(p.se,r-l+1);
        flip[q.fi]^=1;
        rt=merge(merge(p.fi,q.fi),q.se);
    }
    
    void print(int x) {
        down(x);
        if(lc) print(lc);
        printf("%d ",x);
        if(rc) print(rc);
    }
    
    int main() {
        srand(time(0)); 
        read(n); read(m);
        rt=build(1,n);
        while(m--) {
            int l,r;
            read(l); read(r);
            rever(l,r);
        }
        print(rt);
        return 0;
    }
    文艺平衡树
    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=1e6+7; 
    typedef long long LL;
    using namespace std;
    int T,tot,rt[N],v[N*25],l[N*25],r[N*25],hr[N*25],sz[N*25];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    #define lc l[x]
    #define rc r[x]
    void update(int x) {sz[x]=sz[lc]+sz[rc]+1;}
    
    int cre(int y) {
        int x=++tot;
        v[x]=y;
        hr[x]=rand();
        sz[x]=1;
        return x;
    }
    
    void copy(int &x,int y) {
        v[x]=v[y];
        lc=l[y]; rc=r[y];
        sz[x]=sz[y];
        hr[x]=hr[y];
    }
    
    int merge(int x,int y) {
        if(!(x*y)) return x^y;
        int t=++tot;
        if(hr[x]<hr[y]) {
            copy(t,x);
            r[t]=merge(r[t],y);
        }
        else {
            copy(t,y);
            l[t]=merge(x,l[t]);
        }
        update(t);
        return t;
    }
    
    #define pr pair<int,int>
    #define fi first
    #define se second
    pr split(int x,int k) {
        if(!x) return make_pair(0,0); 
        int t=++tot;
        copy(t,x);
        pr p;
        if(sz[l[t]]>=k) {
            p=split(l[t],k);
            l[t]=p.se; p.se=t;
        }
        else {
            p=split(r[t],k-sz[l[t]]-1);
            r[t]=p.fi; p.fi=t; 
        }
        update(t);
        return p;
    }
    
    int rank(int rtt,int y) {
        int res=1;
        for(int x=rtt;x;) {
            if(v[x]<y) res+=(sz[lc]+1),x=rc;
            else x=lc;
        }
        return res;
    }
    
    void insert(int &x,int y) {
        int k=rank(x,y);
        pr p=split(x,k-1);
        int z=cre(y);
        x=merge(merge(p.fi,z),p.se);
    }
    
    int exist(int rtt,int y) {
        for(int x=rtt;x;) {
            if(v[x]==y) return 1;
            if(v[x]<y) x=rc;
            else x=lc;
        }
        return 0;
    }
    
    void del(int &x,int y) {
        if(!exist(x,y)) return;
        int k=rank(x,y);
        pr p=split(x,k-1);
        pr q=split(p.se,1);
        x=merge(p.fi,q.se);
    }
    
    
    int kth(int root,int k) {
        for(int x=root;x;) {
            if(sz[lc]+1==k) return v[x];
            if(sz[lc]+1<k) {k-=(sz[lc]+1); x=rc;}
            else x=lc;
        }
    }
    
    void pre(int root,int y) {
        int res=-1;
        for(int x=root;x;) {
            if(v[x]<y) res=v[x],x=rc;
            else x=lc;
        }
        if(res==-1) printf("-2147483647
    ");
        else printf("%d
    ",res);
    }
    
    void nxt(int root,int y) {
        int res=-1;
        for(int x=root;x;) {
            if(v[x]>y) res=v[x],x=lc;
            else x=rc;
        }
        if(res==-1) printf("2147483647
    ");
        else printf("%d
    ",res);
    }
    
    #define DEBUG
    int main() {
    #ifdef DEBUG
        freopen("testdata.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
        srand(time(0));
        read(T);
        for(int i=1;i<=T;i++) {
            if(i==100) {
                int debug=1;
            }
            int p,o,x;
            read(p); read(o); read(x);
            rt[i]=rt[p];
            switch(o) {
                case 1:insert(rt[i],x);break;
                case 2:del(rt[i],x);break;
                case 3:printf("%d
    ",rank(rt[i],x));break; 
                case 4:printf("%d
    ",kth(rt[i],x));break; 
                case 5:pre(rt[i],x);break; 
                case 6:nxt(rt[i],x);break; 
            } 
        }
        return 0;
    }
    可持久化treap
  • 相关阅读:
    巩固复习(对以前的随笔总结)_01
    Django 项目分析后得到的某些结论
    django 命令行命令
    实现搜索视频到播放(非原创)
    python 打包
    随笔汇总,温故知新
    找伙伴
    sam-Toy Cars
    反质数
    Blue Mary的战役地图
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8021432.html
Copyright © 2011-2022 走看看