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 }