平衡树(Splay):Splaytree POJ 3580 SuperMemo

SuperMemo      
 

Description

Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:

  1. ADD x y D: Add D to each number in sub-sequence {Ax ... Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
  2. REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
  3. REVOLVE x y T: rotate sub-sequence {Ax ... AyT times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
  4. INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
  5. DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
  6. MIN x y: query the participant what is the minimum number in sub-sequence {Ax ... Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2

To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.

Input

The first line contains (≤ 100000).

The following n lines describe the sequence.

Then follows M (≤ 100000), the numbers of operations and queries.

The following M lines describe the operations and queries.

Output

For each "MIN" query, output the correct answer.

Sample Input

5
1 
2 
3 
4 
5
2
ADD 2 4 1
MIN 4 5

Sample Output

5

  
  这也许是我目前见过最全面的平衡树的题目了,相信把这题搞透之后,平衡树也就差不多了,呃。
  tips:这题我交了好多次才AC ~~~

  

  思路其实很简单,主要是程序实现和各种细节给跪了。
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 const int maxn=200010;
  6 const int INF=2147483647;
  7 int Min[maxn],key[maxn],fa[maxn],ch[maxn][2];
  8 int flip[maxn],add[maxn],sz[maxn],rt,cnt,n,Q;
  9 
 10 void Push_up(int p){
 11     Min[p]=min(key[p],min(Min[ch[p][0]],Min[ch[p][1]]));
 12     sz[p]=sz[ch[p][0]]+sz[ch[p][1]]+1;
 13 }
 14 
 15 void Add(int p,int d){
 16     if(p){
 17         Min[p]+=d;
 18         key[p]+=d;
 19         add[p]+=d;
 20     }
 21 }
 22 
 23 void Flip(int p){
 24     swap(ch[p][0],ch[p][1]);
 25     flip[p]^=1;
 26 }
 27 
 28 void Push_down(int p){
 29     if(add[p]){
 30         Add(ch[p][0],add[p]);
 31         Add(ch[p][1],add[p]);
 32         add[p]=0;
 33     }
 34     if(flip[p]){
 35         Flip(ch[p][0]);
 36         Flip(ch[p][1]);
 37         flip[p]=0;
 38     }
 39 }
 40 
 41 void Rotate(int x){
 42     int y=fa[x],g=fa[y],c=ch[y][1]==x;
 43     ch[y][c]=ch[x][c^1];
 44     fa[ch[x][c^1]]=y;fa[y]=x;
 45     ch[x][c^1]=y;fa[x]=g;
 46     if(g)
 47         ch[g][ch[g][1]==y]=x;
 48     Push_up(y);    
 49 }
 50     
 51 void Splay(int x,int g=0){
 52     for(int y;(y=fa[x])!=g;Rotate(x))
 53         if(fa[y]!=g)
 54             Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
 55     Push_up(x);
 56     if(!g)
 57         rt=x;
 58 }
 59 
 60 void Make_root(int x,int g=0){
 61     int p=rt;
 62     while(true){
 63         Push_down(p);
 64         if(sz[ch[p][0]]+1==x)break;
 65         if(sz[ch[p][0]]+1<x){
 66             x-=sz[ch[p][0]]+1;
 67             p=ch[p][1];
 68         }
 69         else
 70             p=ch[p][0];
 71     }
 72     Splay(p,g);
 73 }
 74 
 75 int Build(int pre,int l,int r){
 76     if(l>r)return 0;
 77     int mid=(l+r)>>1;
 78     ch[mid][0]=Build(mid,l,mid-1);
 79     if(mid>1&&mid<n)
 80         scanf("%d",&key[mid]);
 81     else    
 82         key[mid]=INF;
 83     Min[mid]=key[mid];
 84     fa[mid]=pre;sz[mid]=1;
 85     ch[mid][1]=Build(mid,mid+1,r);
 86     Push_up(mid);
 87     return mid;    
 88 }
 89 
 90 int main(){
 91     Min[0]=2147482647;
 92     scanf("%d",&n);n+=2;
 93     rt=Build(0,1,n);cnt=n;
 94     scanf("%d",&Q);
 95     char s[10];int a,b,x;
 96     while(Q--){
 97         scanf("%s",s);
 98         if(!strcmp(s,"ADD")){
 99             scanf("%d%d%d",&a,&b,&x);a++;b++;
100             Make_root(a-1);
101             Make_root(b+1,rt);
102             Push_down(rt);
103             Push_down(ch[rt][1]);
104             Add(ch[ch[rt][1]][0],x);
105         }
106         else if(!strcmp(s,"MIN")){
107             scanf("%d%d",&a,&b);a++;b++;
108             Make_root(a-1);
109             Make_root(b+1,rt);
110             Push_down(rt);
111             Push_down(ch[rt][1]);
112             printf("%d\n",Min[ch[ch[rt][1]][0]]);
113         }
114         else if(!strcmp(s,"DELETE")){
115             scanf("%d",&x);x++;
116             Make_root(x-1);
117             Make_root(x+1,rt);
118             ch[ch[rt][1]][0]=0;
119             Push_up(ch[rt][1]);
120             Push_up(rt);
121         }
122         else if(!strcmp(s,"REVERSE")){
123             scanf("%d%d",&a,&b);a++;b++;
124             Make_root(a-1);
125             Make_root(b+1,rt);
126             Flip(ch[ch[rt][1]][0]);
127         }
128         else if(!strcmp(s,"INSERT")){
129             scanf("%d%d",&a,&x);a++;
130             Make_root(a);
131             Make_root(a+1,rt);
132             int p=++cnt;sz[p]=1;
133             ch[ch[rt][1]][0]=p;
134             key[p]=Min[p]=x;
135             fa[p]=ch[rt][1];
136             Push_up(ch[rt][1]);
137             Push_up(rt);
138         }
139         else if(!strcmp(s,"REVOLVE"))
140         {
141             scanf("%d%d%d",&a,&b,&x);a++;b++;
142             Make_root(a-1);
143             Make_root(b+1,rt);
144             x%=b-a+1;
145             if(x){
146                 Make_root(b-x);
147                 Make_root(b+1,rt);
148                 int tmp=ch[ch[rt][1]][0];
149                 ch[ch[rt][1]][0]=0;
150                 Push_up(ch[rt][1]);
151                 Push_up(rt);
152                 Make_root(a-1);
153                 Make_root(a,rt);
154                 ch[ch[rt][1]][0]=tmp;
155                 fa[tmp]=ch[rt][1];
156                 Push_up(ch[rt][1]);
157                 Push_up(rt);
158             }
159         }
160     }
161     return 0;
162 }

 

  时隔多月,我学会了treap,再AC了一遍。
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 using namespace std;
  6 const int maxn=200010;
  7 const int INF=2147483647;
  8 int key[maxn],flip[maxn],add[maxn],cnt,rt;
  9 int Min[maxn],sz[maxn],ch[maxn][2],fix[maxn];
 10 int x,y,z,t1,t2;
 11 struct Treap{
 12     void Init(){
 13         Min[0]=INF;
 14         //srand(time(NULL)); poj上不能在G++上用这个,否则RE
 15     }
 16     
 17     int Newnode(int v){
 18         sz[++cnt]=1;
 19         Min[cnt]=key[cnt]=v;
 20         flip[cnt]=add[cnt]=0;
 21         ch[cnt][0]=ch[cnt][1]=0;
 22         fix[cnt]=rand();
 23         return cnt;
 24     }
 25     
 26     void Push_up(int x){
 27         sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
 28         Min[x]=min(min(Min[ch[x][0]],Min[ch[x][1]]),key[x]);
 29     }
 30     
 31     void Flip(int x){
 32         swap(ch[x][0],ch[x][1]);
 33         flip[x]^=1;
 34     }
 35     
 36     void Add(int x,int d){
 37         if(!x)return;
 38         key[x]+=d;
 39         Min[x]+=d;
 40         add[x]+=d;
 41     }
 42     
 43     void Push_down(int x){
 44         if(add[x]){
 45             Add(ch[x][0],add[x]);
 46             Add(ch[x][1],add[x]);
 47             add[x]=0;
 48         }
 49         if(flip[x]){
 50             Flip(ch[x][0]);
 51             Flip(ch[x][1]);
 52             flip[x]=0;
 53         }
 54     }
 55     
 56     int Merge(int x,int y){
 57         if(!x||!y)return x|y;
 58         Push_down(x);
 59         Push_down(y);
 60         if(fix[x]<=fix[y]){
 61             ch[x][1]=Merge(ch[x][1],y);
 62             Push_up(x);
 63             return x;
 64         }
 65         else{
 66             ch[y][0]=Merge(x,ch[y][0]);
 67             Push_up(y);
 68             return y;
 69         }
 70     }
 71     
 72     void Split(int x,int k){
 73         Push_down(x);
 74         if(k>sz[x]){t1=x;t2=0;return;}
 75         
 76         if(sz[ch[x][0]]+1==k){
 77             t1=ch[x][0];t2=x;
 78             ch[x][0]=0;
 79             Push_up(x);
 80             return;
 81         }
 82         
 83         if(sz[ch[x][0]]+1<k){
 84             k-=sz[ch[x][0]]+1;
 85             Split(ch[x][1],k);
 86             ch[x][1]=t1;t1=x;
 87             Push_up(x);
 88         }
 89         
 90         else{
 91             Split(ch[x][0],k);
 92             ch[x][0]=t2;t2=x;
 93             Push_up(x);
 94         }
 95     }
 96     
 97     
 98     void Insert(int k,int v){
 99         Split(rt,k+1);
100         t1=Merge(t1,Newnode(v));
101         rt=Merge(t1,t2);
102     }
103     
104     void Delete(int k){
105         int tmp;
106         Split(rt,k);tmp=t1;
107         Split(t2,2);t1=tmp;
108         rt=Merge(t1,t2);
109     }
110     
111     void Divide(int l,int r){
112         Split(rt,l);x=t1;
113         Split(t2,r-l+2);y=t1;z=t2;
114     }
115     
116     void Converge(){
117         x=Merge(x,y);
118         rt=Merge(x,z);
119     }
120     
121     void Add(int l,int r,int d){
122         Divide(l,r);Add(y,d);
123         Converge();
124     }
125     
126     void Reverse(int l,int r){
127         Divide(l,r);Flip(y);
128         Converge();
129     }
130     
131     void Revolve(int l,int r,int k){
132         Divide(l,r);
133         k%=sz[y];
134         if(k){
135             Split(y,sz[y]-k+1);
136             y=Merge(t2,t1);
137         }        
138         Converge();
139     }
140     
141     int Query(int l,int r){
142         Divide(l,r);
143         int ret=Min[y];
144         Converge();
145         return ret;
146     }
147 }T;
148 
149 int n,Q;
150 char op[10];
151 
152 int main(){
153     T.Init();
154     scanf("%d",&n);
155     for(int i=1,a;i<=n;i++){
156         scanf("%d",&a);
157         T.Insert(i,a);
158     }
159     int l,r,k;
160     scanf("%d",&Q);
161     while(Q--){
162         scanf("%s",op);
163         if(!strcmp(op,"ADD")){
164             scanf("%d%d%d",&l,&r,&k);
165             T.Add(l,r,k);
166         }
167         else if(!strcmp(op,"REVERSE")){
168             scanf("%d%d",&l,&r);
169             T.Reverse(l,r);
170         }
171         else if(!strcmp(op,"REVOLVE")){
172             scanf("%d%d%d",&l,&r,&k);
173             T.Revolve(l,r,k);
174         }
175         else if(!strcmp(op,"INSERT")){
176             scanf("%d%d",&l,&k);
177             T.Insert(l,k);
178         }
179         else if(!strcmp(op,"DELETE")){
180             scanf("%d",&k);
181             T.Delete(k);
182         }
183         else if(!strcmp(op,"MIN")){
184             scanf("%d%d",&l,&r);
185             printf("%d\n",T.Query(l,r));
186         }
187     }
188     return 0;
189 }

  有些地方没打好,很丑……

  决定日后整理为模板。




posted @ 2016-02-20 16:44  TenderRun  阅读(494)  评论(0编辑  收藏  举报