文艺平衡树(无旋treap)

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 struct NODE{
  8     NODE *ls,*rs;
  9     int r,s,v;
 10     int rev;
 11     #define size(x) ((x)?(x)->s:0)
 12     NODE(int v=0):v(v){
 13         r=rand();
 14         ls=rs=NULL;
 15         s=1;
 16         rev=0;
 17     }
 18     void reverse(){
 19         if(!this) return;
 20         swap(ls,rs);
 21         rev^=1;
 22     }
 23     void pushdown(){
 24         if(!this) return;
 25         if(rev){
 26             ls->reverse();
 27             rs->reverse();
 28             rev^=1;
 29         }
 30     }
 31     void mt(){
 32         s=1+size(ls)+size(rs);
 33     }
 34 };
 35 
 36 typedef NODE *pnode;
 37 typedef pair<NODE*,NODE*>droot;
 38 NODE *merge(NODE *a,NODE *b){//treap为了满足中序序列,左右子树不能交换 
 39     if(!a) return b;
 40     if(!b) return a;
 41     if(a->r < b->r){//小根堆 
 42         a->pushdown();
 43         a->rs=merge(a->rs,b);
 44         a->mt();
 45         return a; 
 46     }
 47     else {
 48         b->pushdown();
 49         b->ls=merge(a,b->ls);
 50         b->mt();
 51         return b;
 52     }
 53 }
 54 droot split(NODE *x,int k){
 55     if(!x) return droot(NULL,NULL);
 56     x->pushdown();
 57     droot r;
 58     if(size(x->ls) >= k){
 59         r=split(x->ls,k);
 60         x->ls=r.second;
 61         x->mt();
 62         r.second=x;
 63     }
 64     else {
 65         r=split(x->rs,k-size(x->ls)-1);
 66         x->rs=r.first;
 67         x->mt();
 68         r.first=x;
 69     }
 70     return r;
 71 }
 72 //名次树用的普通写法
 73 int kth(NODE *x,int k){//
 74     if(!x || k<=0 || k>size(x)) return 0;
 75     int s=size(x->rs);
 76     if(k == s+1) return x->v;
 77     else if(k <= s) return kth(x->ls,k);
 78     else return kth(x->rs,k-size(x->ls)-1);
 79 } 
 80 int rank(NODE *x,int v){
 81     if(!x) return 0;
 82     if(v < x->v) return rank(x->ls,v);
 83     else return rank(x->rs,v)+size(x->ls)+1;
 84 }
 85 NODE *insert(NODE *root,int v){
 86     int k=rank(root,v);
 87     droot x=split(root,k);
 88     NODE *o=new NODE(v);
 89     return merge(merge(x.first,o),x.second);
 90 }
 91 NODE *build(int *a,int n){
 92     pnode *stk=new pnode[n];
 93     NODE *last;
 94     int tp=0;
 95     for(int i=1;i<=n;i++){
 96         NODE *p=new NODE(i);
 97         last=NULL;
 98         while(tp && stk[tp-1]->r > p->r){
 99             stk[tp-1]->mt();
100             last=stk[tp-1];
101             stk[--tp]=NULL;
102         }
103         if(tp) stk[tp-1]->rs=p;
104         p->ls=last;
105         stk[tp++]=p;
106     }
107     while(tp) stk[--tp]->mt();
108     NODE *r=stk[0];
109     delete []stk;
110     return r;
111 }
112 
113 void dfs(NODE *u){
114     if(!u) return;
115     u->pushdown();
116     dfs(u->ls);
117     printf("%d ",u->v);
118     dfs(u->rs);
119 }
120 
121 int n,m;
122 int d[100010];
123 int main(){
124     freopen("sph.in", "r", stdin);
125     freopen("sph.out", "w", stdout);
126     scanf("%d %d",&n,&m);
127     NODE *t=build(d,n);
128     while(m--){
129         int l,r;
130         scanf("%d %d",&l,&r);
131         droot p1=split(t,l-1);
132         droot p2=split(p1.second,r-l+1);
133         p2.first->reverse();
134         t=merge(p1.first,merge(p2.first,p2.second));
135     }
136     dfs(t);
137     return(0);
138 }
原文地址:https://www.cnblogs.com/KCkowk/p/6477199.html