treap修订

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<ctime>
  5 #include<queue>
  6 #include<cctype>
  7 #include<cstring>
  8 #include<iostream>
  9 #define PAU putchar(' ')
 10 #define ENT putchar('\n')
 11 #define CH for(int d=0;d<=1;d++) if(ch[d])
 12 using namespace std;
 13 const int maxn=200000+10;
 14 struct node{
 15     node*ch[2];int r,v,siz;
 16     void init(){r=rand();siz=1;ch[0]=ch[1]=NULL;return;}
 17     void update(){siz=1;CH{siz+=ch[d]->siz;}return;}
 18 }treap[maxn],*root[maxn],*nodecnt=treap;
 19 queue<node*>RAM;
 20 node*newnode(){
 21     node*x;
 22     if(!RAM.empty()) x=RAM.front(),RAM.pop();
 23     else x=nodecnt++;
 24     x->init();return x;
 25 }
 26 void del(node*&x){RAM.push(x);return;}
 27 void rotate(node*&x,int d){
 28     node*k=x->ch[d^1];x->ch[d^1]=k->ch[d];k->ch[d]=x;
 29     x->update();k->update();x=k;return;
 30 }
 31 void insert(node*&x,int v){
 32     if(!x) x=newnode(),x->v=v;
 33     else{
 34         int d=v>x->v;insert(x->ch[d],v);
 35         if(x->ch[d]->r>x->r) rotate(x,d^1);
 36         else x->update();
 37     } return;
 38 }
 39 void remove(node*&x,int v){
 40     if(x->v==v){
 41         if(x->ch[0]&&x->ch[1]){
 42             int d=x->ch[0]->r>x->ch[1]->r;
 43             rotate(x,d);remove(x->ch[d],v);
 44         }
 45         else{
 46             node*k=x;
 47             if(x->ch[0]) x=x->ch[0];
 48             else x=x->ch[1];
 49             del(k);
 50         }
 51     }
 52     else remove(x->ch[v>x->v],v);
 53     if(x) x->update();return;
 54 }
 55 void print(node*&x){
 56     if(!x) return;
 57     print(x->ch[0]);
 58     printf("%d ",x->v);
 59     print(x->ch[1]);
 60     return;
 61 }
 62 int find(node*x,int rank){
 63     if(x->siz<rank||rank<1) return -1;
 64     int kth=x->ch[0]?x->ch[0]->siz+1:1;
 65     if(kth==rank) return x->v;
 66     if(kth>rank) return find(x->ch[0],rank);
 67     else return find(x->ch[1],rank-kth);
 68 }
 69 int fa[maxn];
 70 int findset(int x){return x==fa[x]?x:fa[x]=findset(fa[x]);}
 71 void merge(node*&x,node*&y){
 72     if(!y)return;if(!x){x=y;del(y);return;}
 73     merge(x,y->ch[0]);
 74     merge(x,y->ch[1]);
 75     insert(x,y->v);
 76     return;
 77 }
 78 void merge(int a,int b){
 79     a=findset(a);b=findset(b);
 80     if(a==b) return;
 81     if(root[a]->siz<root[b]->siz) swap(a,b);
 82     merge(root[a],root[b]);fa[b]=a;
 83     return;
 84 }
 85 inline int read(){
 86     int x=0,sig=1;char ch=getchar();
 87     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
 88     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
 89     return x*=sig;
 90 }
 91 inline char readc(){
 92     char ch=getchar();
 93     while(!isalpha(ch)) ch=getchar();
 94     return ch;
 95 }
 96 inline void write(int x){
 97     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
 98     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 99     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
100 }
101 int n,q,v[maxn];
102 void init(){
103     srand(time(0));
104     n=read();q=read();
105     for(int i=1;i<=n;i++) root[i]=newnode(),v[i]=root[i]->v=read(),fa[i]=i;
106     return;
107 }
108 void work(){
109     int a,b;char tp;
110     while(q--){
111         tp=readc();a=read();b=read();
112         if(tp=='b') merge(a,b);
113         else if(tp=='q') write(find(root[findset(a)],b)),ENT;
114         else{
115             remove(root[findset(a)],v[a]);
116             insert(root[findset(a)],b);
117             v[a]=b;
118         }
119     }
120     return;
121 }
122 void print(){
123     return;
124 }
125 int main(){init();work();print();return 0;}

 

posted @ 2015-07-24 09:10  AI_Believer  阅读(126)  评论(0编辑  收藏  举报