题目大意:给你六个操作,让你实现这些功能。
解题思路:伸展树的基本应用,用伸展数实现各种功能。
SuperMemo
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 10404 | Accepted: 3320 | |
Case Time Limit: 2000MS |
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
5 1 2 3 4 5 2 ADD 2 4 1 MIN 4 5
Sample Output
5
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <iomanip> #include <stdio.h> #include <string> #include <queue> #include <cmath> #include <stack> #include <ctime> #include <map> #include <set> #define eps 1e-9 ///#define M 1000100 ///#define LL __int64 #define LL long long ///#define INF 0x7ffffff #define INF 0x3f3f3f3f #define PI 3.1415926535898 #define zero(x) ((fabs(x)<eps)?0:x) #define mod 1000000007 #define Read() freopen("autocomplete.in","r",stdin) #define Write() freopen("autocomplete.out","w",stdout) #define Cin() ios::sync_with_stdio(false) using namespace std; const int maxn = 220000; #define root10 ch[ch[root][1]][0] #define root1 ch[root][1] #define root11 ch[ch[root][1]][1] #define lson ch[x][0] #define rson ch[x][1] int ch[maxn][2]; int pre[maxn]; int root, tot; int size[maxn]; int val[maxn]; int lazy[maxn]; int xmin[maxn]; int rev[maxn]; int num[maxn]; int st[maxn]; void Treaval(int x) { if(x) { Treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],val[x]); Treaval(ch[x][1]); } } void debug() { printf("root:%d\n",root); Treaval(root); } void push_down(int x) { if(lazy[x]) { if(lson) { lazy[lson] += lazy[x]; val[lson] += lazy[x]; xmin[lson] += lazy[x]; } if(rson) { lazy[rson] += lazy[x]; val[rson] += lazy[x]; xmin[rson] += lazy[x]; } lazy[x] = 0; } if(rev[x]) { rev[lson] ^= 1; rev[rson] ^= 1; swap(lson, rson); rev[x] = 0; } } void push_up(int x) { size[x] = size[lson]+size[rson]+1; xmin[x] = val[x]; if(lson) xmin[x] = min(xmin[x], xmin[lson]); if(rson) xmin[x] = min(xmin[x], xmin[rson]); } void rot(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); push_up(x); } void sply(int x, int goal) { push_down(x); while(pre[x] != goal) { if(pre[pre[x]] == goal) { push_down(pre[x]); push_down(x); rot(x, ch[pre[x]][0] == x); } else { int y = pre[x]; push_down(pre[y]); push_down(y); push_down(x); int kind = ch[pre[y]][0] == y; if(ch[y][kind] == x) { rot(x, !kind); rot(x, kind); } else { rot(y, kind); rot(x, kind); } } } push_up(x); if(goal == 0) root = x; } void init() { root = tot = 0; size[0] = 0; memset(ch, 0, sizeof(ch)); memset(pre, 0, sizeof(pre)); } void newnode(int &x, int k, int father) { x = ++tot; pre[x] = father; size[x] = 1; ch[x][0] = ch[x][1] = 0; val[x] = k; rev[x] = lazy[x] = 0; xmin[x] = k; } void bulidtree(int &x, int l, int r, int father) { if(l > r) return; int mid = (l+r)>>1; newnode(x, num[mid], father); bulidtree(ch[x][0], l, mid-1, x); bulidtree(ch[x][1], mid+1, r, x); push_up(x); } int get_kth(int x, int k) { push_down(x); int p = size[ch[x][0]]; if(p+1 == k) return x; else if(k <= p) return get_kth(ch[x][0], k); else return get_kth(ch[x][1], k-p-1); } int get_max(int r) { push_down(r); while(ch[r][1]) { r = ch[r][1]; push_down(r); } return r; } int get_min(int r) { push_down(r); while(ch[r][0]) { r = ch[r][0]; push_down(r); } return r; } int main() { int n; int q, a, b, c; while(~scanf("%d",&n)) { for(int i = 1; i <= n; i++) scanf("%d",&num[i]); init(); newnode(root, INF, 0); newnode(root1, INF, root); size[root] = 2; bulidtree(root10, 1, n, root1); push_up(root1); push_up(root); debug(); scanf("%d",&q); char str[110]; while(q--) { scanf("%s",str); if(str[0] == 'A') { scanf("%d %d %d",&a, &b, &c); if(a > b) swap(a, b); int x = get_kth(root, a); int y = get_kth(root, b+2); sply(x, 0); sply(y, root); lazy[root10] += c; val[root10] += c; xmin[root10] += c; } else if(str[0] == 'R' && str[3] == 'E') { scanf("%d %d", &a, &b); if(a > b) swap(a, b); int x = get_kth(root, a); int y = get_kth(root, b+2); sply(x, 0); sply(y, root); rev[root10] ^= 1; } else if(str[0] == 'R' && str[3] == 'O') { scanf("%d %d %d",&a, &b, &c); if(a > b) swap(a, b); int m = b-a+1; c = c%m; c = (m+c)%m; if(c == 0) continue; int x = get_kth(root, a); int y = get_kth(root, a+1); int xx = get_kth(root, b-c+1); int yy = get_kth(root, b+2); sply(xx, 0); sply(yy, root); int ps = root10; root10 = 0; push_up(root1); push_up(root); sply(x, 0); sply(y, root); root10 = ps; pre[ps] = root1; push_up(root1); push_up(root); } else if(str[0] == 'I') { scanf("%d %d",&a, &b); int x = get_kth(root, a+1); int y = get_kth(root, a+2); sply(x, 0); sply(y, root); newnode(root10, b, root1); push_up(root1); push_up(root); } else if(str[0] == 'D') { scanf("%d",&a); int x = get_kth(root, a); int y = get_kth(root, a+2); sply(x, 0); sply(y, root); root10 = 0; push_up(root1); push_up(root); } else if(str[0] == 'M') { scanf("%d %d",&a, &b); if(a > b) swap(a, b); int x = get_kth(root, a); int y = get_kth(root, b+2); sply(x, 0); sply(y, root); printf("%d\n",xmin[root10]); } } } return 0; }