SuperMemo
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 12795   Accepted: 3989
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
/*
poj3580 splay树 REVOVLE循环
给定一个数列:a1,a2,.... an
进行以下6种操作:
ADD x y D : 给第x个数到第y个数加D
REVERSE x y : 反转[x,y]
REVOVLE x y T : 对[x,y]区间的数循环右移T次 (这个最开始没想到这么弄)
(先把T对长度取模,然后相当于把[y-T+1,y]放到[x,y-T] 的前面,T可能出现负数或者特别大)
INSERT x P : 在第x个数后面插入P
DELETE 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循环的更多相关文章

  1. Splay树-Codevs 1296 营业额统计

    Codevs 1296 营业额统计 题目描述 Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司 ...

  2. ZOJ3765 Lights Splay树

    非常裸的一棵Splay树,需要询问的是区间gcd,但是区间上每个数分成了两种状态,做的时候分别存在val[2]的数组里就好.区间gcd的时候基本上不支持区间的操作了吧..不然你一个区间里加一个数gcd ...

  3. Splay树再学习

    队友最近可能在学Splay,然后让我敲下HDU1754的题,其实是很裸的一个线段树,不过用下Splay也无妨,他说他双旋超时,单旋过了,所以我就敲来看下.但是之前写的那个Splay越发的觉得不能看,所 ...

  4. 暑假学习日记:Splay树

    从昨天开始我就想学这个伸展树了,今天花了一个上午2个多小时加下午2个多小时,学习了一下伸展树(Splay树),学习的时候主要是看别人博客啦~发现下面这个博客挺不错的http://zakir.is-pr ...

  5. 1439. Battle with You-Know-Who(splay树)

    1439 路漫漫其修远兮~ 手抄一枚splay树 长长的模版.. 关于spaly树的讲解   网上很多随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找.删除特 ...

  6. 伸展树(Splay树)的简要操作

    伸展树(splay树),是二叉排序树的一种.[两个月之前写过,今天突然想写个博客...] 伸展树和一般的二叉排序树不同的是,在每次执行完插入.查询.删除等操作后,都会自动平衡这棵树.(说是自动,也就是 ...

  7. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  8. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  9. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

随机推荐

  1. Beta集合

    Beta冲刺day1 Beta冲刺day2 Beta冲刺day3 Beta冲刺day4 Beta冲刺day5 Beta冲刺day6 Beta冲刺day7 测试总结 总结合集 Beta预备

  2. 使用Putty连接Amazon EC2 Instance

    Amazon的EC2中,默认是不允许使用用户名和密码直接连接Instance的,而是通过AWS (Amazon Web Service)提供的证书.在第一次使用EC2的时候,AWS会要求你创建一个证书 ...

  3. 函数式编程之foldLeftViaFoldRight

    问题来自 Scala 函数式编程 一书的习题, 让我很困扰, 感觉函数式编程有点神学的感觉.后面看懂之后, 又觉得函数式编程所提供的高阶抽象是多么的强大. 这个问题让我发呆了好久, 现在把自己形成的想 ...

  4. css3动画transition详解

    一.transition-property 语法: transition-property : none | all | [ <IDENT> ] [ ',' <IDENT> ] ...

  5. Ansible性能调优

    Ansible企业实战环境中,如果管理的服务器越来越多,Ansibe执行效率会变得比较慢,可以通过优化Ansible提供工作效率,由于Ansible基于SSH协议通信,SSH连接慢会导致整个基于Ans ...

  6. Python内置函数(14)——bytes

    英文文档: class bytes([source[, encoding[, errors]]]) Return a new "bytes" object, which is an ...

  7. Python-面向对象(一)-Day7

    Day7-面向对象基础 1一.isinstance(obj, cls) 1二.issubclass(sub, super) 1三.异常处理 11.异常基础 12.异常种类 23.异常其他结构 54.主 ...

  8. 新概念英语(1-a)句子集锦

  9. MySql入门(2-2)创建数据库

    mysql -u root -p; show databases; create database apigateway; use apigateway; show tables;

  10. python当中的 可迭代对象 迭代器

    学习python有一段时间了,在学习过程中遇到很多难理解的东西,做一下总结,希望能对其他朋友有一些帮助. 完全是个人理解,难免有错,欢迎其他大神朋友们批评指正. 1 迭代 什么是迭代呢??我们可以这样 ...