poj3580 splay树 REVOVLE循环
来源:互联网 发布:长波电台事件 知乎 编辑:程序博客网 时间:2024/05/23 11:09
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
/*poj3580 splay树 REVOVLE循环给定一个数列:a1,a2,.... an进行以下6种操作:ADD x y D : 给第x个数到第y个数加DREVERSE x y : 反转[x,y]REVOVLE x y T : 对[x,y]区间的数循环右移T次 (这个最开始没想到这么弄)(先把T对长度取模,然后相当于把[y-T+1,y]放到[x,y-T] 的前面,T可能出现负数或者特别大)INSERT x P : 在第x个数后面插入PDELETE x : 删除第x个数 MIN x y : 查询[x,y]之间的最小的数像min,add是参照rev,size来写。然后就只有第三个操作可以一开始想不到,其它大致就是各种基本操作的组合了最开始写错del导致TLE几次hhh-2016-02-21 03:06:02*/#include <functional>#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <map>#include <cmath>using namespace std;typedef long long ll;typedef long double ld;#define key_value ch[ch[root][1]][0]const int maxn = 200010;int ch[maxn][2];int pre[maxn],siz[maxn],num[maxn];int rev[maxn],key[maxn];int add[maxn];int Min[maxn],a[maxn];int tot;int root;void push_up(int r){ int lson = ch[r][0],rson = ch[r][1]; siz[r] = siz[lson] + siz[rson] + 1; Min[r] = min(key[r],min(Min[lson],Min[rson]));}void update_add(int r,int val){ if(!r) return; key[r] += val; add[r] += val; Min[r] += val;}void update_rev(int r){ if(!r)return ; swap(ch[r][0],ch[r][1]); rev[r] ^= 1;}void push_down(int r){ if(rev[r]) { update_rev(ch[r][0]); update_rev(ch[r][1]); rev[r] = 0; } if(add[r]) { update_add(ch[r][0],add[r]); update_add(ch[r][1],add[r]); add[r] = 0; }}void NewNode(int &r,int far,int k){ r = ++tot; //不能为0 pre[r] = far; ch[r][0] = ch[r][1] = 0; siz[r] = 1; Min[r] = k; key[r] = k; rev[r] = 0; add[r] = 0;}void rotat(int x,int kind){ int y = pre[x]; push_down(y); push_down(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; push_up(y);}void build(int &x,int l,int r,int far){ if(l > r) return ; int mid = (l+r) >>1; NewNode(x,far,a[mid]); build(ch[x][0],l,mid-1,x); build(ch[x][1],mid+1,r,x); push_up(x);}void splay(int r,int goal){ push_down(r); while(pre[r] != goal) { if(pre[pre[r]] == goal) { push_down(pre[r]); push_down(r); rotat(r,ch[pre[r]][0] == r); } else { push_down(pre[pre[r]]); push_down(pre[r]); push_down(r); int y = pre[r]; int kind = ch[pre[y]][0] == y; if(ch[y][kind] == r) { rotat(r,!kind); rotat(r,kind); } else { rotat(y,kind); rotat(r,kind); } } } push_up(r); if(goal == 0) root = r;}int get_kth(int r,int k){ push_down(r); int t = siz[ch[r][0]] + 1; if(k == t)return r; if(t > k) return get_kth(ch[r][0],k); else return get_kth(ch[r][1],k-t);}int get_next(int r){ push_down(r); if(ch[r][1] == 0)return -1; r = ch[r][1]; while(ch[r][0]) { r = ch[r][0]; push_down(r); } return r;}void Reverse(int l,int r){ splay(get_kth(root,l),0); splay(get_kth(root,r+2),root); update_rev(key_value); push_up(ch[root][1]); push_up(root);}void Add(int l,int r,int val){ splay(get_kth(root,l),0); splay(get_kth(root,r+2),root); update_add(key_value,val); push_up(ch[root][1]); push_up(root);}void ini(int n){ tot = root = 0; ch[root][0] = ch[root][1] = pre[root] = siz[root] = num[root] = 0; Min[root] = 0x3f3f3f3f; rev[root] = add[root] = 0; NewNode(root,0,-1); NewNode(ch[root][1],root,-1); for(int i=1; i <= n; i++) { scanf("%d",&a[i]); } build(key_value,1,n,ch[root][1]); push_up(ch[root][1]); push_up(root);}int get_min(int r){ push_down(r); while(ch[r][0]) { r = ch[r][0]; push_down(r); } return r;}void Delete(int r){ splay(get_kth(root,r+1),0); if(ch[root][0] == 0 || ch[root][1] == 0) { root = ch[root][0] + ch[root][1]; pre[root] = 0; return; } int k = get_min(ch[root][1]); splay(k,root); ch[ch[root][1]][0] = ch[root][0]; root = ch[root][1]; pre[ch[root][0]] = root; pre[root] = 0; push_up(root);}void Insert(int x,int y){ splay(get_kth(root,x+1),0); splay(get_kth(root,x+2),root); NewNode(key_value,ch[root][1],y); push_up(ch[root][1]); push_up(root);}int MIN(int x,int y){ splay(get_kth(root,x),0); splay(get_kth(root,y+2),root); push_up(ch[root][1]); push_up(root); return Min[key_value];}void Revovle(int x,int y,int T){ splay(get_kth(root,y-T+1),0); splay(get_kth(root,y+2),root); int tmp = key_value; //pre[key_value] = 0; key_value = 0; push_up(ch[root][1]); push_up(root); splay(get_kth(root,x),0); splay(get_kth(root,x+1),root); key_value = tmp; pre[key_value] = ch[root][1]; push_up(ch[root][1]); push_up(root);}int main(){ int n,p; while(scanf("%d",&n) != EOF) { ini(n); scanf("%d",&p); char opr[20]; int x,y,z; while(p--) { scanf("%s",opr); if(strcmp(opr,"ADD") == 0) { scanf("%d%d%d",&x,&y,&z); Add(x,y,z); } else if(strcmp(opr,"INSERT") == 0) { scanf("%d%d",&x,&y); Insert(x,y); } else if(strcmp(opr,"DELETE") == 0) { scanf("%d",&x); Delete(x); } else if(strcmp(opr,"MIN") == 0) { scanf("%d%d",&x,&y); printf("%d\n",MIN(x,y));// for(int i =1;i <= 5;i++)// printf("%d\n",Min[i]); } else if(strcmp(opr,"REVERSE") == 0) { scanf("%d%d",&x,&y); Reverse(x,y); } else if(strcmp(opr,"REVOLVE") == 0) { scanf("%d%d%d",&x,&y,&z); int t = (y-x+1); z = (z%t+t)%t; Revovle(x,y,z); } } } return 0;}
- poj3580 splay树 REVOVLE循环
- poj3580 SuperMemo 伸展树 splay
- poj3580 splay
- POJ3580 splay
- 【poj3580】【splay】SuperMemo
- poj3580 SuperMemo (splay)
- POJ3580 SuperMemo (Splay)
- POJ3580 SuperMemo(Splay)
- 【序列之神splay】poj3580
- POJ3580[memo] 旋转吧,splay!
- POJ3580 SuperMemo(Splay的区间操作)
- poj3580:SuperMemo(块状链表/Splay)
- poj3580
- POJ3580
- 【Splay|Treap】poj3580 SuperMemo && bzoj1503 [noi2004]郁闷的出纳员
- poj3580 SuperMemo (Splay+区间内向一个方向移动)
- POJ3580 SuperMemo (Splay Tree的各种操作)
- 伸展树(区间加值,反转,循环移动,插入,删除区间,求区间最小值)poj3580
- 条款
- 【12】AutoCompleteTextView——自动完成文本框
- 《Hadoop:The Definitive Guide 4th Edition》Chapter 17 Hive——B部分
- zoj2112 树状数组+主席树 区间动第k大
- [leetcode] 215. Kth Largest Element in an Array 解题报告
- poj3580 splay树 REVOVLE循环
- [BZOJ 1941]Hide and Seek
- C#中将调试信息记录到文件中去
- Haoop selfjoin 左表 右表 自连接
- 1037. 在霍格沃茨找零钱
- 如何解决某个端口被谁占用?
- 搭建C++开发开发环境
- 想做女性方面的手游
- Git学习初级篇(上)