首页 > 代码库 > POJ3580---SuperMemo (Splay)
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 else119 {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 else131 {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 else150 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_JUDGE213 freopen("in.txt","r",stdin);214 #endif215 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 }
POJ3580---SuperMemo (Splay)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。