【普通平衡树】
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; }