POJ 3580 SuperMemo(Splay树)
来源:互联网 发布:2017dnf商人起步必知 编辑:程序博客网 时间:2024/05/21 03:26
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, {A1, A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:
- 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}
- 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}
- REVOLVE x y T: rotate sub-sequence {Ax ... Ay} T times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
- 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}
- DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
- 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 n (n ≤ 100000).
The following n lines describe the sequence.
Then follows M (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
51 2 3 4 52ADD 2 4 1MIN 4 5
Sample Output
5
Source
题意:
add x,y D:第x个数到第y个数之间的数每个加D;
reverse x y:第x个数到第y个数之间全部数翻转;
revolve x y T:第x个数到第y个数之间的数,向后循环流动T次,即后面T个数变成这段子序列的最前面T个,前面的被挤到后面。
insert x P:在第x个数后面插入一个数P。
delete x:删除第x个数。
min x,y:求第x个数到第y个数之间的最小数字。
代码:
#include <cstdio>#include <cmath>#include <algorithm>using namespace std;typedef long long LL;const LL INF = 1e18;const int maxn = 200005;int a[maxn];int ch[maxn][2], fa[maxn];int sz[maxn], rev[maxn];LL val[maxn], sum[maxn], add[maxn], Min[maxn];int tol, rt;void newNode(int p, int __val, int __fa){ val[p] = __val; sum[p] = __val; Min[p] = __val; fa[p] = __fa; sz[p] = 1; rev[p] = add[p] = 0; ch[p][0] = ch[p][1] = 0;}void mark_add(int p, LL __add){ add[p] += __add; val[p] += __add; sum[p] += __add * sz[p]; Min[p] += __add;}void mark_rev(int p){ rev[p] ^= 1; swap(ch[p][0], ch[p][1]);}void push_down(int p){ if(rev[p]){ mark_rev(ch[p][0]); mark_rev(ch[p][1]); rev[p] = 0; } if(add[p]){ mark_add(ch[p][0], add[p]); mark_add(ch[p][1], add[p]); add[p] = 0; }}void push_up(int p){ int ls = ch[p][0], rs = ch[p][1]; sz[p] = sz[ls] + sz[rs] + 1; sum[p] = sum[ls] + sum[rs] + val[p]; Min[p] = min(val[p], min(Min[ls], Min[rs]));}void Rotate(int x, int t){ int p = fa[x]; push_down(p); push_down(x); fa[x] = fa[p]; if(fa[p]) ch[fa[p]][ch[fa[p]][1] == p] = x; ch[p][!t] = ch[x][t]; if(ch[x][t]) fa[ch[x][t]] = p; ch[x][t] = p; fa[p] = x; push_up(p);}void splay(int x, int y){ if(!x) return; push_down(x); while(fa[x] != y){ int p = fa[x]; if(fa[p] == y){ push_down(p); push_down(x); Rotate(x, ch[p][0] == x); }else{ int g = fa[p]; push_down(g); push_down(p); push_down(x); if(ch[g][0] == p){ if(ch[p][0] == x){ Rotate(p, 1); Rotate(x, 1); }else{ Rotate(x, 0); Rotate(x, 1); } }else{ if(ch[p][1] == x){ Rotate(p, 0); Rotate(x, 0); }else{ Rotate(x, 1); Rotate(x, 0); } } } } push_up(x); if(!y) rt = x;}int build(int l, int r, int fa){ if(l > r) return 0; int mid = (l + r) >> 1; newNode(mid, a[mid], fa); ch[mid][0] = build(l, mid - 1, mid); ch[mid][1] = build(mid + 1, r, mid); push_up(mid); return mid;}int get_pos(int k){ int p = rt; while(1){ push_down(p); if(sz[ch[p][0]] >= k) p = ch[p][0]; else if(sz[ch[p][0]] + 1 == k) break; else{ k -= sz[ch[p][0]] + 1; p = ch[p][1]; } } return p;}void Add(int a, int b, int c){ int pre = get_pos(a - 1); int nxt = get_pos(b + 1); splay(pre, 0); splay(nxt, pre); mark_add(ch[nxt][0], c); push_up(nxt); push_up(pre);}void Rev(int a, int b){ int pre = get_pos(a - 1); int nxt = get_pos(b + 1); splay(pre, 0); splay(nxt, pre); mark_rev(ch[nxt][0]); push_up(nxt); push_up(pre);}void Ins(int x, int P){ int nxt = get_pos(x + 1); int now = get_pos(x); splay(nxt, 0); splay(now, nxt); ch[now][1] = ++tol; newNode(ch[now][1], P, now); push_up(now); push_up(nxt);}void Del(int x){ int pre = get_pos(x - 1); int nxt = get_pos(x + 1); splay(pre, 0); splay(nxt, pre); ch[nxt][0] = 0; push_up(nxt); push_up(pre);}void Revolve(int a, int b, int T){ //[a, c - 1], [c, b] int l = b - a + 1; int g = (T % l + l) % l + 1; if(g == 1) return;//原样不动!//删除[c, b] int c = a + l - g + 1; int pre = get_pos(c - 1); int nxt = get_pos(b + 1); splay(pre, 0); splay(nxt, pre); int p = ch[nxt][0]; ch[nxt][0] = 0; push_up(nxt); push_up(pre);//将[c, b]插入a的前面 pre = get_pos(a - 1); nxt = get_pos(a); splay(pre, 0); splay(nxt, pre); ch[nxt][0] = p; fa[p] = nxt; push_up(nxt); push_up(pre);}int get_min(int a, int b){ int pre = get_pos(a - 1); int nxt = get_pos(b + 1); splay(pre, 0); splay(nxt, pre); return Min[ch[nxt][0]];}void init(int n){ tol = 0; ch[0][0] = ch[0][1] = fa[0] = sz[0] = rev[0] = 0; val[0] = sum[0] = add[0] = 0; Min[0] = INF; newNode(rt = n + 1, 0, 0); newNode(ch[rt][1] = n + 2, 0, rt); ch[ch[rt][1]][0] = build(1, n, ch[rt][1]); tol = n + 2;}int main(){ int n, m, x, y, D, P, T; char opt[10]; while(scanf("%d", &n) != EOF){ for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); } init(n); scanf("%d", &m); while(m--){ scanf("%s", opt); if(opt[0] == 'A'){ scanf("%d%d%d", &x, &y, &D); x++; y++; Add(x, y, D); }else if(opt[0] == 'R' && opt[3] == 'E'){ scanf("%d%d", &x, &y); x++; y++; Rev(x, y); }else if(opt[0] == 'R'){ scanf("%d%d%d", &x, &y, &T); x++; y++; Revolve(x, y, T); }else if(opt[0] == 'I'){ scanf("%d%d", &x, &P); x++; Ins(x, P); }else if(opt[0] == 'D'){ scanf("%d", &x); x++; Del(x); }else{ scanf("%d%d", &x, &y); x++; y++; printf("%d\n", get_min(x, y)); } } } return 0;}
- POJ-3580 SuperMemo(Splay树)
- POJ 3580 SuperMemo(Splay树)
- POJ 3580 SuperMemo (Splay)
- 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树,经典题)
- Splay树(多操作)——POJ 3580 SuperMemo
- poj 3580 SuperMemo(伸展树splay)
- poj 3580 SuperMemo splay树模板题
- BZOJ 1895 & POJ 3580 supermemo (splay)
- POJ 3580 SuperMemo (Splay tree)
- POJ 3580 SuperMemo (SPLAY TREE)
- 用List的时候遇到的一个空指针异常
- 前端(前台)工程师和后端(后台)工程师的区别
- 面向对象(二)——操作符重载 & 关键字this & 静态成员static
- CountDownLatch和CyclicBarrier的简单使用
- java中组合和继承的结合使用
- POJ 3580 SuperMemo(Splay树)
- CreateObject("Mercury.DeviceReplay")中的键盘值
- Android Studio中使用adb shell查看SharedPreferences文件
- 对 PInvoke 函数“...”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配
- 主键外键与索引
- [Java多线程 九]---JUC包下并发集合类
- vs2013 InstallShield打包卸载程序
- 机器学习第十课part3之Boost总结
- LeetCode Construct String from Binary Tree