Poj 3580-SuperMemo Splay

题目:http://poj.org/problem?id=3580

 
SuperMemo
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 13105   Accepted: 4104
Case Time Limit: 2000MS

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

Source

 
题意:给定一个序列,每次执行一个操作,对于每个min输出即可。
题解:
好个码农题。。。
Splay处理一下区间翻转,区间加上k,区间左右移动(循环序列),区间查询。。。
记得开long long。。。。。。
代码:
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define MAXN 100010
  4 #define MAXM 100010
  5 #define INF 1e9
  6 #define LL long long
  7 struct node
  8 {
  9     LL left,right,mn,val,size;
 10 }tree[MAXN+MAXM];
 11 LL a[MAXN+MAXM],father[MAXN+MAXM],rev[MAXN+MAXM],tag[MAXN+MAXM];
 12 LL read()
 13 {
 14     LL s=0,fh=1;char ch=getchar();
 15     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
 16     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
 17     return s*fh;
 18 }
 19 void Pushup(LL x)
 20 {
 21     LL l=tree[x].left,r=tree[x].right;
 22     tree[x].size=tree[l].size+tree[r].size+1;
 23     tree[x].mn=min(min(tree[l].mn,tree[r].mn),tree[x].val);
 24 }
 25 void Build(LL l,LL r,LL f)
 26 {
 27     if(l>r)return;
 28     LL now=l,last=f;
 29     if(l==r)
 30     {
 31         tree[now].val=tree[now].mn=a[l];father[now]=last;
 32         tree[now].size=1;
 33         if(l<f)tree[last].left=now;
 34         else tree[last].right=now;
 35     }
 36     LL mid=(l+r)/2;
 37     now=mid;
 38     Build(l,mid-1,mid);Build(mid+1,r,mid);
 39     father[now]=last;tree[now].val=a[mid];
 40     Pushup(now);
 41     if(mid<f)tree[last].left=now;
 42     else tree[last].right=now;
 43 }
 44 /*void Pushup(int x)
 45   {
 46   int l=tree[x].left,r=tree[x].right;
 47   tree[x].size=tree[l].size+tree[r].size+1;
 48   tree[x].mn=min(min(tree[l].mn,tree[r].mn),tree[x].val);
 49   }*/
 50 void rotate(LL x,LL &root)
 51 {
 52     LL y=father[x],z=father[y];
 53     if(y==root)root=x;
 54     else
 55     {
 56         if(tree[z].left==y)tree[z].left=x;
 57         else tree[z].right=x;
 58     }
 59     if(tree[y].left==x)
 60     {
 61         father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y;
 62     }
 63     else
 64     {
 65         father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y;
 66     }
 67     Pushup(y);Pushup(x);
 68 }
 69 void Splay(LL x,LL &root)
 70 {
 71     while(x!=root)
 72     {
 73         int y=father[x],z=father[y];
 74         if(y!=root)
 75         {
 76             if((tree[y].left==x)^(tree[z].left==y))rotate(x,root);
 77             else rotate(y,root);
 78         }
 79         rotate(x,root);
 80     }
 81 }
 82 void Pushdown(LL x)
 83 {
 84     LL l=tree[x].left,r=tree[x].right;
 85     if(tag[x]!=0)
 86     {
 87         tag[l]+=tag[x];tag[r]+=tag[x];
 88         tree[l].val+=tag[x];tree[r].val+=tag[x];
 89         tree[l].mn+=tag[x];tree[r].mn+=tag[x];
 90         tag[x]=0;
 91     }
 92     if(rev[x]!=0)
 93     {
 94         rev[l]^=1;rev[r]^=1;rev[x]^=1;
 95         swap(tree[x].left,tree[x].right);
 96     }
 97 }
 98 LL Find(LL root,LL rank)
 99 {
100     Pushdown(root);
101     if(tree[tree[root].left].size+1==rank)return root;
102     else if(rank<=tree[tree[root].left].size)return Find(tree[root].left,rank);
103     else return Find(tree[root].right,rank-tree[tree[root].left].size-1);
104 }
105 int main()
106 {
107     LL n,m,i,rt,SIZE,l,r,add,x,y,z,L,R,T,X,P;
108     char fh[8];
109     n=read();
110     tree[0].val=INF;a[0]=tree[0].mn=INF;
111     tree[1].val=INF;tree[n+2].val=INF;
112     tree[1].mn=INF;tree[n+2].mn=INF;
113     a[1]=INF;a[n+2]=INF;
114     for(i=2;i<=n+1;i++)a[i]=read(),tree[i].val=tree[i].mn=INF;
115     Build(1,n+2,0);
116     SIZE=n+2;rt=(1+n+2)/2;
117     m=read();
118     for(i=1;i<=m;i++)
119     {
120         scanf("\n%s",fh);
121         if(fh[0]=='A')
122         {
123             l=read();r=read();add=read();
124             x=Find(rt,l);y=Find(rt,r+2);
125             Splay(x,rt);Splay(y,tree[x].right);
126             z=tree[y].left;
127             tag[z]+=add;tree[z].val+=add;tree[z].mn+=add;
128         }
129         else if(fh[0]=='R')
130         {
131             if(fh[3]=='E')
132             {
133                 l=read();r=read();
134                 x=Find(rt,l);y=Find(rt,r+2);
135                 Splay(x,rt);Splay(y,tree[x].right);
136                 z=tree[y].left;
137                 rev[z]^=1;
138             }
139             else
140             {
141                 l=read();r=read();T=read();
142                 L=l;R=r;
143                 T=(T%(r-l+1)+(r-l+1))%(r-l+1);
144                 if(T==0)continue;
145                 l=r-T+1;
146                 x=Find(rt,l);y=Find(rt,r+2);
147                 Splay(x,rt);Splay(y,tree[x].right);
148                 z=tree[y].left;
149                 father[z]=0;tree[y].left=0;
150                 Pushup(y);Pushup(x);
151                 x=Find(rt,L);y=Find(rt,L+1);
152                 Splay(x,rt);Splay(y,tree[x].right);
153                 father[z]=y;tree[y].left=z;
154                 Pushup(y);Pushup(x);
155             }
156         }
157         else if(fh[0]=='I')
158         {
159             X=read();P=read();
160             x=Find(rt,X+1);y=Find(rt,X+2);
161             Splay(x,rt);Splay(y,tree[x].right);
162             tree[y].left=++SIZE;tree[SIZE].val=P;
163             father[SIZE]=y;tree[SIZE].size=1;
164             tree[SIZE].mn=P;
165             Pushup(y);Pushup(x);
166         }
167         else if(fh[0]=='D')
168         {
169             X=read();
170             x=Find(rt,X);y=Find(rt,X+2);
171             Splay(x,rt);Splay(y,tree[x].right);
172             z=tree[y].left;tree[y].left=0;
173             tree[z].size=0;father[z]=0;
174             //tree[SIZE].val=INF;tree[SIZE].mn=INF;
175             Pushup(y);Pushup(x);
176         }
177         else
178         {
179             l=read();r=read();
180             x=Find(rt,l);y=Find(rt,r+2);
181             Splay(x,rt);Splay(y,tree[x].right);
182             z=tree[y].left;
183             printf("%lld\n",tree[z].mn);
184         }
185     }
186     fclose(stdin);
187     fclose(stdout);
188     return 0;
189 }
View Code

 

posted @ 2016-03-15 17:12  微弱的世界  阅读(143)  评论(0编辑  收藏  举报