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. ExecutorService,另一种服务,线程

    http://heipark.iteye.com/blog/1393847 Executors.newFixedThreadPool和ArrayBlockingQueue一点使用心得       博客 ...

  2. java unicode和字符串间的转换

    package ykxw.web.jyf; /** * Created by jyf on 2017/5/16. */ public class unicode { public static voi ...

  3. 让linux远程主机在后台运行脚本

    后台挂起:python xxx.py & 在脚本命令后面加入"&"符号就可以后台运行.结束进程:kill -9 sidps -ef | grep ... 查询sid

  4. C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现

    我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...

  5. Win7添加php环境变量.

    1) "我的电脑"右键"属性"->高级系统设置->环境变量->系统变量->Path->编辑 2) 将PHP的执行路径的目录&quo ...

  6. sublimeText3 中配置sass环境,并将编译后文件保存到指定文件夹

    sass基于ruby引擎,所以安装时ass.compass之前需要安装ruby.具体的链接应该是(http://rubyinstaller.org/downloads).下载并安装相应的版本,勾选第二 ...

  7. linux 进程间通信的3种高级方式及优缺点

    由于不同的进程运行在各自不同的内存空间中.一方对于变量的修改另一方是无法感知的.因此.进程之间的信息传递不可能通过变量或其它数据结构直接进行,只能通进程间通信来完成. 根据进程通信时信息量大小的不同, ...

  8. hadoop2.6.0实践:A01 问题处理 DEPRECATED: Use of this script to execute hdfs command is deprecated.

    [hadoop@hadoop-master data]$ hadoop dfs -ls /DEPRECATED: Use of this script to execute hdfs command ...

  9. 页面加载loading动画

    关于页面加载的loading动画,能度娘到的大部分都是通过定时器+蒙层实现的,虽然表面上实现了动画效果,实际上动化进程和页面加载进程是没有什么关系的,只是设置几秒钟之后关闭蒙层,但假如页面须要加载的元 ...

  10. spring boot 中active的profile会和标准配置合并吗

    如下图,两个profile配置文件,一个默认的(application.properties),一个是test的. 活跃配置为test. spring.profiles.active=test ste ...