POJ 3580 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;
}
相關文章
- 對伸展樹的伸展操作理解
- 伸展樹Java實現Java
- 伸展樹(Splay)學習筆記筆記
- 二叉樹的基本操作二叉樹
- POJ 3468 A Simple Problem with Integers(線段樹區間操作)
- 二叉樹的應用(1)--二叉樹排序樹基本操作二叉樹排序
- 夜刷:平衡二叉樹的基本操作二叉樹
- POJ 1418 圓的基本操作以及 圓弧離散化
- 樹狀陣列3種基本操作陣列
- [演算法] 資料結構 splay(伸展樹)解析演算法資料結構
- 坐下,這些都是二叉樹的基本操作!二叉樹
- POJ 基本演算法演算法
- poj 2481 樹狀陣列陣列
- POJ3107Godfather[樹形DP 樹的重心]Go
- 樹的基本概念
- Go 操作 Redis 的基本操作GoRedis
- 伸展樹 【資料結構與演算法分析 c 語言描述】資料結構演算法
- POJ 2486 Apple Tree(樹形dp)APP
- Docker的基本操作Docker
- MySQL的基本操作MySql
- git的基本操作Git
- 模組的基本操作
- 棧的基本操作
- webdriver的基本操作Web
- hash的基本操作
- 樹(1)--樹和二叉樹的基本定義二叉樹
- POJ 3928 Ping pong(樹狀陣列)陣列
- POJ 3107 Godfather(樹形dp)Go
- 活動(Activity)的基本操作
- JS — 物件的基本操作JS物件
- react的基本操作(1)React
- Hive表的基本操作Hive
- Vim命令的基本操作
- Numpy的基本操作(五)
- Hbase shell的基本操作
- git的基本操作(一)Git
- Docker映象的基本操作Docker
- 佇列的基本操作佇列