POJ3580---SuperMemo (Splay)

各种操作,区间更新,求最值、翻转、插入、删除、当然是Splay这种神器了。

主要是 revolve这个操作,其实也就是3个区间翻转放到一块,

比如 REVOLVE x y T,T %= (y-x+1); 其实就是 先把 x y区间翻转,然后把  x x + c - 1区间和 x+ c  y区间分别翻转。

代码:

  1 #include <set>
  2 #include <map>
  3 #include <cmath>
  4 #include <ctime>
  5 #include <queue>
  6 #include <stack>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 typedef unsigned long long ull;
 16 typedef long long ll;
 17 const int inf = 0x3f3f3f3f;
 18 const double eps = 1e-8;
 19 const int maxn = 1e5+100;
 20 int siz[maxn],minv[maxn],rev[maxn],addv[maxn],key[maxn];
 21 int ch[maxn][2],a[maxn],pre[maxn],s[maxn];
 22 int n,tot1,tot2,root;
 23 void NewNode(int &r,int father,int k)
 24 {
 25     if (tot2)
 26         r = s[tot2--];
 27     else
 28         r = ++tot1;
 29     pre[r] = father;
 30     key[r] = k;
 31     siz[r] = 1;
 32     minv[r] = k;
 33     ch[r][0] = ch[r][1] = 0;
 34 }
 35 void update_Rev(int r)
 36 {
 37     if (!r)
 38         return ;
 39     swap(ch[r][0],ch[r][1]);
 40     rev[r] ^= 1;
 41 }
 42 void push_up(int r)
 43 {
 44     siz[r] = siz[ch[r][0]] + siz[ch[r][1]] + 1;
 45     minv[r] = min(key[r],min(minv[ch[r][0]],minv[ch[r][1]]));
 46 }
 47 void update_add(int r,int val)
 48 {
 49     if (!r)
 50         return ;
 51     key[r] += val;
 52     addv[r] += val;
 53     minv[r] += val;
 54 }
 55 void push_down(int r)
 56 {
 57     if (rev[r])
 58     {
 59         update_Rev(ch[r][0]);
 60         update_Rev(ch[r][1]);
 61         rev[r] = 0;
 62     }
 63     if (addv[r])
 64     {
 65         update_add(ch[r][0],addv[r]);
 66         update_add(ch[r][1],addv[r]);
 67         addv[r] = 0;
 68     }
 69 }
 70 
 71 void build(int &x,int l,int r,int father)
 72 {
 73     if (l > r)
 74         return;
 75     int mid = (l + r) >> 1;
 76     NewNode(x,father,a[mid]);
 77     build(ch[x][0],l,mid-1,x);
 78     build(ch[x][1],mid+1,r,x);
 79     push_up(x);
 80 }
 81 void init()
 82 {
 83     tot1 = root = tot2 = 0;
 84     for (int i = 1; i <= n; i++)
 85         scanf ("%d",a+i);
 86     minv[root] = inf;
 87     NewNode(root,0,-1);
 88     NewNode(ch[root][1],root,-1);
 89     build(ch[ch[root][1]][0],1,n,ch[root][1]);
 90     push_up(root);
 91     push_up(ch[root][1]);
 92 }
 93 void Rotate(int x,int kind)
 94 {
 95     int y = pre[x];
 96     push_down(y);
 97     push_down(x);
 98     ch[y][!kind] = ch[x][kind];
 99     pre[ch[x][kind]] = y;
100     if (pre[y])
101         ch[pre[y]][ch[pre[y]][1] == y] = x;
102     pre[x] = pre[y];
103     ch[x][kind] = y;
104     pre[y] = x;
105     push_up(y);
106 }
107 void Splay(int r,int goal)
108 {
109     push_down(r);
110     while (pre[r] != goal)
111     {
112         if (pre[pre[r]] == goal)
113         {
114             push_down(pre[r]);
115             push_down(r);
116             Rotate(r,ch[pre[r]][0] == r);
117         }
118         else
119         {
120             int y = pre[r];
121             push_down(pre[y]);
122             push_down(y);
123             push_down(r);
124             int kind = (ch[pre[y]][1] == y);
125             if (ch[y][kind] == r)
126             {
127                 Rotate(y,!kind);
128                 Rotate(r,!kind);
129             }
130             else
131             {
132                 Rotate(r,kind);
133                 Rotate(r,!kind);
134             }
135         }
136     }
137     push_up(r);
138     if (goal == 0)
139         root = r;
140 }
141 int Get_kth(int r,int k)
142 {
143     push_down(r);
144     int t = siz[ch[r][0]] + 1;
145     if (t == k)
146         return r;
147     else if (t <= k)
148         return Get_kth(ch[r][1],k-t);
149     else
150         return Get_kth(ch[r][0],k);
151 }
152 void eraser(int r)
153 {
154     if (!r)
155         return;
156     s[++tot2] = r;
157     eraser(ch[r][0]);
158     eraser(ch[r][1]);
159 }
160 void Delete(int x)
161 {
162     Splay(Get_kth(root,x),0);
163     Splay(Get_kth(root,x+2),root);
164     eraser(ch[ch[root][1]][0]);
165     pre[ch[ch[root][1]][0]] = 0;
166     ch[ch[root][1]][0] = 0;
167     push_up(ch[root][1]);
168     push_up(root);
169 }
170 void Insert(int x,int val)
171 {
172     Splay(Get_kth(root,x+1),0);
173     Splay(Get_kth(root,x+2),root);
174     NewNode(ch[ch[root][1]][0],ch[root][1],val);
175     push_up(ch[root][1]);
176     push_up(root);
177 }
178 void ADD(int u,int v,int val)
179 {
180     Splay(Get_kth(root,u),0);
181     Splay(Get_kth(root,v+2),root);
182     update_add(ch[ch[root][1]][0],val);
183     push_up(ch[root][1]);
184     push_up(root);
185 }
186 int query(int ua,int ub)
187 {
188     Splay(Get_kth(root,ua),0);
189     Splay(Get_kth(root,ub+2),root);
190     return minv[ch[ch[root][1]][0]];
191 }
192 void Reverse (int u,int v)
193 {
194     Splay (Get_kth(root,u),0);
195     Splay (Get_kth(root,v+2),root);
196     update_Rev (ch[ch[root][1]][0]);
197     push_up (ch[root][1]);
198     push_up (root);
199 }
200 void revolve(int u,int v,int c)
201 {
202     int len = (v - u + 1);
203     c  %= len;
204     if (!c)
205         return;
206     Reverse(u,v);
207     Reverse(u,u+c-1);
208     Reverse(u+c,v);
209 }
210 int main(void)
211 {
212     #ifndef ONLINE_JUDGE
213         freopen("in.txt","r",stdin);
214     #endif
215     while (~scanf ("%d",&n))
216     {
217         init();
218         int m;
219         scanf ("%d",&m);
220         for (int i = 0; i < m; i++)
221         {
222             char op[10];
223             int u,v,c;
224             scanf ("%s",op);
225             if (strcmp(op,"ADD") == 0)
226             {
227                 scanf ("%d%d%d",&u,&v,&c);
228                 ADD(u,v,c);
229             }
230             if (strcmp(op,"REVERSE") == 0)
231             {
232                 scanf ("%d%d",&u,&v);
233                 Reverse(u,v);
234             }
235             if (strcmp(op,"REVOLVE") == 0)
236             {
237                 scanf ("%d%d%d",&u,&v,&c);
238                 revolve(u,v,c);
239             }
240             if (strcmp(op,"INSERT") == 0)
241             {
242                 scanf ("%d%d",&u,&v);
243                 Insert(u,v);
244             }
245             if (strcmp(op,"DELETE") == 0)
246             {
247                 scanf ("%d",&u);
248                 Delete(u);
249             }
250             if (strcmp(op,"MIN") == 0)
251             {
252                 scanf ("%d%d",&u,&v);
253                 printf("%d\n",query(u,v));
254             }
255         }
256     }
257     return 0;
258 }

 

posted @ 2014-11-06 21:51  PlasticSpirit  阅读(364)  评论(0编辑  收藏  举报