非旋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\n",rank(x));break;
            case 4:printf("%d\n",kth(x));break;
            case 5:printf("%d\n",pre(x));break;
            case 6:printf("%d\n",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\n");
    else printf("%d\n",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\n");
    else printf("%d\n",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\n",rank(rt[i],x));break; 
            case 4:printf("%d\n",kth(rt[i],x));break; 
            case 5:pre(rt[i],x);break; 
            case 6:nxt(rt[i],x);break; 
        } 
    }
    return 0;
}
可持久化treap

 

posted @ 2017-12-11 07:14  啊宸  阅读(116)  评论(0编辑  收藏  举报