平衡树:Splaytree POJ 3580 SuperMemo

SuperMemo

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 12788   Accepted: 3986
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, {A1A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:

  1. 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}
  2. 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}
  3. REVOLVE x y T: rotate sub-sequence {Ax ... AyT times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
  4. 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}
  5. DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
  6. 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 (≤ 100000).

The following n lines describe the sequence.

Then follows 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
    这也许是我目前见过最难的平衡树的题目了,相信把这题搞透之后,平衡树也就差不多了  tips:这题我交了50次才对 ~~~

  

  思路其实很简单,主要是程序实现和各种细节。
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 using namespace std;
  7 const int maxn=200010;
  8 const int INF=2147483647;
  9 int Min[maxn],key[maxn],ch[maxn][2],fa[maxn],flip[maxn],Mark[maxn],size[maxn],root,cnt;
 10
 11 void Push_up(int p)
 12 {
 13     if(!p)return;
 14     Min[p]=min(key[p],min(Min[ch[p][0]],Min[ch[p][1]]));
 15     size[p]=size[ch[p][0]]+size[ch[p][1]]+1;
 16 }
 17 void Add(int p,int d)
 18 {
 19     if(!p)return;
 20     Min[p]+=d;
 21     key[p]+=d;
 22     Mark[p]+=d;
 23 }
 24 void Flip(int p)
 25 {
 26     if(!p)return;
 27     swap(ch[p][0],ch[p][1]);
 28     flip[p]^=1;
 29 }
 30 void Push_down(int p)
 31 {
 32     if(Mark[p]){
 33         Add(ch[p][0],Mark[p]);
 34         Add(ch[p][1],Mark[p]);
 35         Mark[p]=0;
 36     }
 37     if(flip[p]){
 38         Flip(ch[p][0]);
 39         Flip(ch[p][1]);
 40         flip[p]=0;
 41     }
 42 }
 43 void Rotate(int x)
 44 {
 45     int y=fa[x],g=fa[y],c=ch[y][1]==x;
 46     ch[y][c]=ch[x][c^1];ch[x][c^1]=y;
 47     fa[ch[y][c]]=y;fa[y]=x;fa[x]=g;
 48     Push_up(y);Push_up(x);
 49     if(g)
 50         ch[g][ch[g][1]==y]=x;
 51 }
 52
 53 void Splay(int x,int g=0)
 54 {
 55     for(int y;(y=fa[x])!=g;Rotate(x))
 56         if(fa[y]!=g)
 57             Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
 58     if(g==0)
 59         root=x;
 60 }
 61
 62 void Bring_up(int x,int g=0)
 63 {
 64     int p=root;
 65     while(true){
 66         Push_down(p);
 67         if(size[ch[p][0]]+1==x)break;
 68         if(size[ch[p][0]]>=x)
 69             p=ch[p][0];
 70         else{
 71             x-=size[ch[p][0]]+1;
 72             p=ch[p][1];
 73         }
 74     }
 75     Splay(p,g);
 76 }
 77 #define Go ch[ch[root][1]][0]
 78 int main()
 79 {
 80     int n,p,l,r,x,Q;
 81     scanf("%d",&n);
 82     Min[0]=INF;size[0]=0;
 83     for(int i=0;i<=n+1;i++)
 84     {
 85         if(i!=0&&i!=n+1)
 86             scanf("%d",&x);
 87         else
 88             x=INF;
 89         p=++cnt;
 90         key[p]=Min[p]=x;
 91         size[p]=1;
 92         if(root)
 93             ch[root][1]=p,fa[p]=root,Rotate(p);
 94         root=p;
 95     }
 96     char s[15];
 97     scanf("%d",&Q);
 98     while(Q--)
 99     {
100         scanf("%s",s);
101         if(!strcmp(s,"MIN")){
102             scanf("%d%d",&l,&r);l++;r++;
103             Bring_up(l-1);
104             Bring_up(r+1,root);
105             Push_down(root);
106             Push_down(ch[root][1]);
107             printf("%d\n",Min[Go]);
108         }
109         else if(!strcmp(s,"ADD")){
110             scanf("%d%d%d",&l,&r,&x);
111             l++;r++;
112             Bring_up(l-1);
113             Bring_up(r+1,root);
114             Add(Go,x);
115             Push_up(ch[root][1]);
116             Push_up(root);
117         }
118         else if(!strcmp(s,"INSERT")){
119             scanf("%d%d",&l,&x);l++;
120             Bring_up(l);
121             Bring_up(l+1,root);
122             Go=++cnt;
123             key[Go]=Min[Go]=x;
124             size[Go]=1;
125             if(root)
126                 fa[Go]=ch[root][1];
127             else
128                 root=Go;
129             Push_up(ch[root][1]);
130             Push_up(root);
131         }
132         else if(!strcmp(s,"DELETE")){
133             scanf("%d",&l);l++;
134             Bring_up(l-1);
135             Bring_up(l+1,root);
136             Go=0;
137             Push_up(ch[root][1]);
138             Push_up(root);
139         }
140         else if(!strcmp(s,"REVERSE")){
141             scanf("%d%d",&l,&r);l++;r++;
142             Bring_up(l-1);
143             Bring_up(r+1,root);
144             Flip(Go);
145         }
146         else if(!strcmp(s,"REVOLVE")){
147             scanf("%d%d%d",&l,&r,&x);l++;r++;
148             x%=r-l+1;
149             if(x==0)continue;
150             Bring_up(r-x);
151             Bring_up(r+1,root);
152             int tmp=Go;Go=0;
153             Push_up(ch[root][1]);
154             Push_up(root);
155             Bring_up(l-1);
156             Bring_up(l,root);
157             Go=tmp;fa[Go]=ch[root][1];
158             Push_up(ch[root][1]);
159             Push_up(root);
160         }
161     }
162     return 0;
163 }
  
时间: 2024-12-16 05:46:03

平衡树:Splaytree POJ 3580 SuperMemo的相关文章

POJ 3580 SuperMemo

裸Splay区间操作: 内存池+区间加减+区间翻转+插入+删除+维护最值 SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8552   Accepted: 2801 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participa

poj 3580 SuperMemo (Splay)

poj 3580 好恶心的题目,真是各种操作都来了个遍 ... 不过Splay树真是一种神奇的东西,通过旋转就能实现各种操作,而且方法也都相差不大 . 题意: 给出一个数字序列,有6种操作: (1) ADD x y d: 第x个数到第y个数加d . (2) REVERSE x y : 将区间[x,y]中的数翻转 . (3) REVOLVE x y t :将区间[x,y]旋转t次,如1 2 3 4 5 旋转2次后就变成4 5 1 2 3 . (4) INSERT x p :在第x个数后面插入p .

poj 3580 SuperMemo splay树模板题

题意: 给一个序列,对其进行各种操作.在对序列仅对操作的处理上,splay是比线段树强大的,虽然均摊复杂度均为logN,但它能支持1:在某个位置插入一些连续的数,2:在某个位置删除一些连续的数.只是splay随便一些200+行. 分析: 网上各种模板介绍漫天飞,这个还算简洁明了. 代码: //poj 3580 #include <stdio.h> #define maxN 200000 int N,T,node; int a[maxN],size[maxN],left[maxN],right[

Splay树(多操作)——POJ 3580 SuperMemo

对应POJ题目:点击打开链接 SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11309   Accepted: 3545 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

POJ 3580 - SuperMemo - [伸展树splay]

题目链接:http://poj.org/problem?id=3580 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 h

又一道Splay吐血题 [POJ 3580] SuperMemo

SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9878   Accepted: 3177 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.

POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)

SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13917   Accepted: 4352 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

POJ 3580 SuperMemo(伸展树的基本操作)

题目大意:给你六个操作,让你实现这些功能. 解题思路:伸展树的基本应用,用伸展数实现各种功能. 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 t

POJ 3580 SuperMemo 题解

题目大意:维护一个序列,支持6种操作: 1.ADD x y D 从第x个数到第y个数都增加D 2.REVERSE x y 翻转第x个数到第y个数 3.REVOLVE x y T 从x到y,向右循环移动T次 4.INSERT x P 插入P到第x个数后面 5.DELETE x 删除第x个数 6.MIN x y 查询第x个数到第y个数之间最小值 ADD和REVERSE打标记然后及时下传就可以..REVOLVE的T可能为负还可能很大,要注意取模.REVOLVE可以通过3个REVERSE操作完成,也可以