poj 3580 SuperMemo(Splay)
来源:互联网 发布:java date json 编辑:程序博客网 时间:2024/05/05 11:59
基本包括了Splay Tree的所有操作,插入,删除,右移,翻转,区间更新,区间查询。学习Splay Tree推荐一个博客,FZU_Jason。这道题基本上就是抄的他的。。
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define CLR(a, b) memset(a, b, memset(a))using namespace std;const int N = 200010;const int INF = 0x7FFFFFFF;struct SplayTree{ int size, root, top; int st[N], a[N]; int ch[N][2], pre[N], key[N], num[N]; //num 当前根下节点个数 int add[N], mini[N]; bool flip[N]; inline void PushUp(int x) { num[x] = num[ch[x][0]] + num[ch[x][1]] + 1; mini[x] = min(mini[ch[x][0]], mini[ch[x][1]]); mini[x] = min(mini[x], key[x]); } inline void PushDown(int x) { int L, R; L = ch[x][0];R = ch[x][1]; if(add[x]) { if(L) { add[L] += add[x]; key[L] += add[x]; mini[L] += add[x]; } if(R) { add[R] += add[x]; key[R] += add[x]; mini[R] += add[x]; } add[x] = 0; } if(flip[x]) { flip[L] ^= true; flip[R] ^= true; swap(ch[x][0], ch[x][1]); flip[x] = false; } } void NewNode(int &x, int father, int val) { if(top != -1) x = st[top --]; else x = ++size; ch[x][0] = ch[x][1] = add[x] = 0; pre[x] = father; key[x] = mini[x] = val; num[x] = 1; flip[x] = false; } void Build(int &x, int L, int R, int father) { if(L <= R) { int mid = (L + R) >> 1; NewNode(x, father, a[mid]); Build(ch[x][0], L, mid - 1, x); Build(ch[x][1], mid + 1, R, x); PushUp(x); } } void Init(int n) { root = size = 0; top = -1; flip[0] = false; ch[0][0] = ch[0][1] = pre[0] = num[0] = add[0] = 0; key[0] = mini[0] = INF; NewNode(root, 0, INF); NewNode(ch[root][1], root, INF); Build(ch[ch[root][1]][0], 1, n, ch[root][1]); PushUp(ch[root][1]); PushUp(root); } void Rotate(int x, int kind) { int y = pre[x]; PushDown(x); ch[y][!kind] = ch[x][kind]; pre[ch[x][kind]] = y; if(pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x; pre[x] = pre[y]; ch[x][kind] = y; pre[y] = x; PushUp(y); } void Splay(int r, int goal) { while(pre[r] != goal) { if(pre[pre[r]] == goal) Rotate(r, ch[pre[r]][0] == r); else { int y = pre[r]; int kind = ch[pre[y]][0] == y; if(ch[y][kind] == r) Rotate(r, !kind), Rotate(r, kind); else Rotate(y, kind), Rotate(r, kind); } } //PushUp(r); if(goal == 0) root = r; } /* void Rotate(int x, int kind) { int y, z; y = pre[x]; z = pre[y]; PushDown(y); ch[y][!kind] = ch[x][kind]; pre[ch[x][kind]] = y; ch[z][ch[z][1] == y] = x; pre[x] = z; ch[x][kind] = y; pre[y] = x; PushUp(y); } void Splay(int x, int goal) { if (x != goal) { PushDown(x); while (pre[x] != goal) { if (ch[pre[x]][0] == x) Rotate(x, 1); else Rotate(x, 0); } PushUp(x); if (!goal) root = x; } } */ int Select(int k) { int x; PushDown(root); for(x = root; num[ch[x][0]] + 1 != k;) { if(num[ch[x][0]] + 1 > k) x = ch[x][0]; else k -= num[ch[x][0]] + 1, x = ch[x][1]; PushDown(x); } return x; } void Add(int x, int y, int val) { int t; x = Select(x - 1); y = Select(y + 1); Splay(x, 0); Splay(y, x); t = ch[y][0]; add[t] += val; key[t] += val; mini[t] += val; PushUp(y); PushUp(x); } void Flip(int x, int y) { x = Select(x - 1); y = Select(y + 1); Splay(x, 0); Splay(y, x); flip[ch[y][0]] ^= true; } void Revolve(int x, int y, int t) { int cnt = y - x + 1; t %= cnt; if(t < 0) t += cnt; if(t) { Flip(x, y - t); Flip(y - t + 1, y); Flip(x, y); } } void Insert(int x, int val) { int a, b; a = Select(x); b = Select(x + 1); Splay(a, 0); Splay(b, a); NewNode(ch[b][0], b, val); PushUp(b); PushUp(a); } void Delete(int x) { int a, b; a = Select(x - 1); b = Select(x + 1); Splay(a, 0); Splay(b, a); st[++ top] = ch[b][0]; ch[b][0] = 0; PushUp(b); PushUp(a); } int MIN(int x, int y) { x = Select(x - 1); y = Select(y + 1); Splay(x, 0); Splay(y, x); return mini[ch[y][0]]; }}spt;int main() { char cmd[18]; int n, q, i; int x, y, val; while (~scanf("%d", &n)) { for (i = 1; i <= n; i++) scanf("%d", &spt.a[i]); spt.Init(n); scanf("%d", &q); while (q--) { scanf(" %s", cmd); if (strcmp(cmd, "ADD") == 0) { scanf("%d%d%d", &x, &y, &val); spt.Add(x + 1, y + 1, val); } else if (strcmp(cmd, "REVERSE") == 0) { scanf("%d%d", &x, &y); spt.Flip(x + 1, y + 1); } else if (strcmp(cmd, "REVOLVE") == 0) { scanf("%d%d%d", &x, &y, &val); spt.Revolve(x + 1, y + 1, val); } else if (strcmp(cmd, "INSERT") == 0) { scanf("%d%d", &x, &val); spt.Insert(x + 1, val); } else if (strcmp(cmd, "DELETE") == 0) { scanf("%d", &x); spt.Delete(x + 1); } else { scanf("%d%d", &x, &y); printf("%d\n", spt.MIN(x + 1, y + 1)); } } } return 0;}
0 0
- splay POJ 3580SuperMemo
- POJ 3580 SuperMemo(Splay)
- POJ 3580 SuperMemo(Splay)
- poj 3580 SuperMemo(Splay)
- poj-3580-SuperMemo-splay
- 【POJ】3580 SuperMemo 【splay】
- POJ 3580 SuperMemo Splay
- POJ 3580 SuperMemo [Splay]
- POJ 3580 SuperMemo (Splay tree)
- POJ 3580 SuperMemo (SPLAY TREE)
- 【splay tree】 POJ 3580 SuperMemo
- POJ 3580 SuperMemo(Splay模板)
- poj-3580 SuperMemo[splay tree]
- POJ 3580 SuperMemo (Splay)
- poj 3580 SuperMemo(伸展树splay)
- POJ 3580 SuperMemo Splay 区间维护
- poj 3580 SuperMemo splay树模板题
- POJ 3580 SuperMemo splay 翻转 右移
- Servlet 工作原理解析
- 采用OGR读postgresql数据库
- 无JavaScript实现选项卡轮转切换效果
- 将博客搬至CSDN
- Ubuntu 12.04 Rhythmbox mp3播放列表乱码的解决办法
- poj 3580 SuperMemo(Splay)
- Unity3D中Animation的常见属性及方法
- git 颜色和快捷 设置
- java Scanner + String练习
- UIView autoresizingMask
- openWRT添加模块
- Spring 注解学习手札(二) 控制层梳理
- MFC的使用
- 第四章、SpringMVC学习-Controller接口控制器详解(5)