Treap的板子

【普通平衡树】

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<ctime>
 7 using namespace std;
 8 template<typename T>T read(){
 9     char c=getchar();int x=0,f=1;
10     for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
11     for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
12     return x*f;
13 }
14 const int maxn=100010;
15 namespace Treap{
16     int num;
17     struct Node{
18         int data,key,sz;
19         int ls,rs;
20         Node(){};
21         Node(int data,int key,int sz,int ls=0,int rs=0):
22             data(data),key(key),sz(sz),ls(ls),rs(rs){};
23     }T[maxn];
24     void pushup(int x){
25         T[x].sz=T[T[x].ls].sz+T[T[x].rs].sz+1;
26     }
27     int newnode(int x){
28         T[++num]=Node(x,rand(),1);
29         return num;
30     }
31     int merge(int x,int y){
32         if(!x||!y)return x+y;
33         if(T[x].key<T[y].key){
34             T[x].rs=merge(T[x].rs,y);
35             pushup(x);
36             return x;
37         }
38         else{
39             T[y].ls=merge(x,T[y].ls);
40             pushup(y);
41             return y;
42         }
43     }
44     void split(int now,int k,int &x,int &y){
45         if(!now){x=y=0;return;}
46         
47         if(T[now].data<=k)x=now,split(T[now].rs,k,T[now].rs,y);
48         else y=now,split(T[now].ls,k,x,T[now].ls);
49         pushup(now);
50     }
51     int kth(int now,int k){
52         while(1){
53             if(k<=T[T[now].ls].sz)now=T[now].ls;
54             else if(k==T[T[now].ls].sz+1)return now;
55             else k-=T[T[now].ls].sz+1,now=T[now].rs;
56         }
57     }
58 }
59 using namespace Treap;
60 int main(){
61     srand(time(0));
62     for(int n=read<int>()+1,rt=0,x,y,z;--n;){
63         int op=read<int>(),a=read<int>();
64         if(op==1){
65             split(rt,a,x,y);
66             rt=merge(merge(x,newnode(a)),y);
67         }
68         else if(op==2){
69             split(rt,a,x,z);split(x,a-1,x,y);
70             y=merge(T[y].ls,T[y].rs);
71             rt=merge(merge(x,y),z);
72         }
73         else if(op==3){
74             split(rt,a-1,x,y);
75             printf("%d\n",T[x].sz+1);
76             rt=merge(x,y);
77         }
78         else if(op==4)printf("%d\n",T[kth(rt,a)].data);
79         else if(op==5){
80             split(rt,a-1,x,y);
81             printf("%d\n",T[kth(x,T[x].sz)].data);
82             rt=merge(x,y);
83         }
84         else if(op==6){
85             split(rt,a,x,y);
86             printf("%d\n",T[kth(y,1)].data);
87             rt=merge(x,y);
88         }
89     }
90     return 0;
91 }

【文艺平衡树】

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct node{
    node *ch[2];
    int data,key,sz,flip;
    int siz(int x){
        if(ch[x]!=NULL)return ch[x]->sz;
        else return 0;
    }
    void pushdown(){
        if(flip){
            flip=0;
            swap(ch[0],ch[1]);
            if(ch[0]!=NULL)ch[0]->flip^=1;
            if(ch[1]!=NULL)ch[1]->flip^=1;
        }
    }
    void maintain(){sz=1+siz(0)+siz(1);}
}*root;
typedef pair<node*,node*> droot;
node *merge(node *a,node *b){
    if(a==NULL)return b;
    if(b==NULL)return a;
    a->pushdown();b->pushdown();
    if(a->key<b->key){
        a->ch[1]=merge(a->ch[1],b);
        a->maintain();
        return a;
    }
    else{
        b->ch[0]=merge(a,b->ch[0]);
        b->maintain();
        return b;
    }
}
droot split(node *a,int k){
    if(a==NULL)return droot(NULL,NULL);
    droot ret;
    a->pushdown();
    if(a->siz(0)>=k){
        ret=split(a->ch[0],k);
        a->ch[0]=ret.second;
        a->maintain();
        ret.second=a;
    }
    else{
        ret=split(a->ch[1],k-a->siz(0)-1);
        a->ch[1]=ret.first;
        a->maintain();
        ret.first=a;
    }
    return ret;
}
void insert(int x){
    node *t=new node;
    t->data=x;t->key=rand();t->sz=1;
    t->flip=0;t->ch[0]=t->ch[1]=NULL;
    root=merge(root,t);
}
void output(node *o){
    if(!o)return;
    o->pushdown();
    if(o->ch[0])output(o->ch[0]);
    printf("%d ",o->data);
    if(o->ch[1])output(o->ch[1]);
}
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)insert(i);
    for(int a,b;m--;){
        scanf("%d%d",&a,&b);
        --a;--b;
        droot s=split(root,a);
        droot t=split(s.second,b-a+1);
        t.first->flip^=1;
        root=merge(merge(s.first,t.first),t.second);
    }
    output(root);
    return 0;
}

 

posted @ 2019-08-07 19:49  人棍王楼下的AI  阅读(173)  评论(0编辑  收藏  举报