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

Source

 /* ***********************************************
Author :kuangbin
Created Time :2013/8/28 19:39:45
File Name :F:\2013ACM练习\专题学习\splay_tree_2\POJ3580.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
/*
* 给定一个数列: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] 的前面)
* INSERT x P : 在第x个数后面插入P
* DELETE x : 删除第x个数
* MIN x y : 查询[x,y]之间的最小的数
*/
#define Key_value ch[ch[root][1]][0]
const int MAXN = ;
const int INF = 0x3f3f3f3f;
int pre[MAXN],ch[MAXN][],root,tot1,size[MAXN];
int key[MAXN],rev[MAXN],m[MAXN],add[MAXN];
int s[MAXN],tot2;
int a[MAXN];
int n;
void NewNode(int &r,int father,int k)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
pre[r] = father;
ch[r][] = ch[r][] = ;
key[r] = k;
m[r] = k;
rev[r] = add[r] = ;
size[r] = ;
}
void Update_Rev(int r)
{
if(!r)return;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
}
void Update_Add(int r,int D)
{
if(!r)return;
m[r] += D;
key[r] += D;
add[r] += D;
}
void push_up(int r)
{
size[r] = size[ch[r][]] + size[ch[r][]] + ;
m[r] = min(key[r],min(m[ch[r][]],m[ch[r][]]));
}
void push_down(int r)
{
if(rev[r])
{
Update_Rev(ch[r][]);
Update_Rev(ch[r][]);
rev[r] = ;
}
if(add[r])
{
Update_Add(ch[r][],add[r]);
Update_Add(ch[r][],add[r]);
add[r] = ;
}
}
void Build(int &x,int l,int r,int father)
{
if(l > r)return;
int mid = (l+ r)/;
NewNode(x,father,a[mid]);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
}
void Init()
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = pre[root] = ;
rev[root] = add[root] = ;
m[root] = INF;
size[root] = ;
NewNode(root,,-);
NewNode(ch[root][],root,-);
for(int i = ;i < n;i++)
scanf("%d",&a[i]);
Build(Key_value,,n-,ch[root][]);
push_up(ch[root][]);
push_up(root);
}
void Rotate(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]][]==y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
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);
Rotate(r,ch[pre[r]][]==r);
}
else
{
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y]][]==y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
push_up(r);
if(goal == ) root = r;
} int Get_kth(int r,int k)
{
push_down(r);
int t = size[ch[r][]] + ;
if(t == k) return r;
if(t > k) return Get_kth(ch[r][],k);
else return Get_kth(ch[r][],k-t);
} void ADD(int x,int y,int D)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,y+),root);
Update_Add(Key_value,D);
push_up(ch[root][]);
push_up(root);
}
void Reverse(int x,int y)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,y+),root);
Update_Rev(Key_value);
push_up(ch[root][]);
push_up(root);
}
void REVOLVE(int x,int y,int T)
{
int len = y - x + ;
T = ( T%len + len )%len;
Splay(Get_kth(root,y-T+),);
Splay(Get_kth(root,y+),root);
int tmp = Key_value;
Key_value = ;
push_up(ch[root][]);
push_up(root);
Splay(Get_kth(root,x),);
Splay(Get_kth(root,x+),root);
Key_value = tmp;
pre[tmp] = ch[root][];
push_up(ch[root][]);
push_up(root);
}
void INSERT(int x,int P)
{
Splay(Get_kth(root,x+),);
Splay(Get_kth(root,x+),root);
NewNode(Key_value,ch[root][],P);
push_up(ch[root][]);
push_up(root);
}
void erase(int r)
{
if(!r)return;
s[++tot2] = r;
erase(ch[r][]);
erase(ch[r][]);
}
void DELETE(int x)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,x+),root);
erase(Key_value);
pre[Key_value] = ;
Key_value = ;
push_up(ch[root][]);
push_up(root);
}
int MIN(int x,int y)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,y+),root);
return m[Key_value];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n) == )
{
Init();
int x,y,z;
char op[];
int q;
scanf("%d",&q);
while(q--)
{
scanf("%s",op);
if(strcmp(op,"ADD") == )
{
scanf("%d%d%d",&x,&y,&z);
ADD(x,y,z);
}
else if(strcmp(op,"REVERSE") == )
{
scanf("%d%d",&x,&y);
Reverse(x,y);
}
else if(strcmp(op,"REVOLVE") == )
{
scanf("%d%d%d",&x,&y,&z);
REVOLVE(x,y,z);
}
else if(strcmp(op,"INSERT") == )
{
scanf("%d%d",&x,&y);
INSERT(x,y);
}
else if(strcmp(op,"DELETE") == )
{
scanf("%d",&x);
DELETE(x);
}
else if(strcmp(op,"MIN") == )
{
scanf("%d%d",&x,&y);
printf("%d\n",MIN(x,y));
}
}
}
return ;
}

POJ 3580 SuperMemo (splay tree)的更多相关文章

  1. 伸展树(Splay Tree)进阶 - 从原理到实现

    目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...

  2. 数据结构(二) --- 伸展树(Splay Tree)

    文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...

  3. 纸上谈兵:伸展树(splay tree)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...

  4. HDU 1890 Robotic Sort (splay tree)

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

  5. 平衡树之伸展树(Splay Tree)题目整理

    目录 前言 练习1 BZOJ 3224 普通平衡树 练习2 BZOJ 3223 文艺平衡树 练习3 BZOJ 1588 [HNOI2002]营业额统计 练习4 BZOJ 1208 [HNOI2004] ...

  6. 伸展树(splay tree)

    伸展树的设计思路,鉴于数据访问的局部性(28原则)在实际应用中普遍存在,将按照"最常用者优先"的启发策略.尽管在最坏情况下其单次操作需要 O(n) 时间,但分摊而言仍然 O(log ...

  7. BZOJ 1269: [AHOI2006]文本编辑器editor (splay tree)

    1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1213  Solved: 454[Submit ...

  8. HDU 3436 Queue-jumpers (splay tree)

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

  9. HDU 1890--Robotic Sort(Splay Tree)

    题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转. 题解:每次把要的区间转成一棵子树,然后更新.因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后 ...

随机推荐

  1. js实现数据视图双向绑定原理

    这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他 ...

  2. java基础49 IO流技术(对象输入流/对象输出流)

    1.对象输入输出流 对象注意作用是用于写对象信息与读取对象信息 1.对象输出流:ObjectOutputStream    2.对象输入流:ObjectInputStream 2.对象输入输出流的步骤 ...

  3. linux内核之accept实现

    用户态对accept的标准用法: if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size) ...

  4. ubuntu和windows双系统启动顺序的修改

    ubuntu和windows双系统启动顺序的修改 说到启动就不得不说GRUB,Linux下大名鼎鼎的启动管理工具(曾经的LILO已经风光不再),当然现在已经是GRUB2了,GRUB2和GRUB最重要的 ...

  5. Java事务管理之Hibernate

    环境与版本 Hibernate 版本:Hibernate 4.2.2 (下载后的文件名为hibernate-release-4.2.2.Final.zip,解压目录hibernate-release- ...

  6. Python 安装 pytesser 处理验证码出现的问题

    今天这个问题困扰了我好久,开始直接用 pip install pytesseract 安装了 pytesseract 然后出现了如下错误 Traceback (most recent call las ...

  7. How to tell your iPhone application that location services are required | The Agile Warrior

    div{padding-bottom:10px}.b_vPanel>div:last-child{padding:0}.banner a{color:#1020d0} --> Below ...

  8. c 语言文本文件判断是否到达结尾的问题

    在c语言中,判断文件结尾有两种方法,第一种是使用feof()函数,feof(fp)用于测试fp所指向的文件的当前状态是否为“文件结束”.如果是,函数则返回的是非0值(真),否则为0(假),要注意的是, ...

  9. 一步一步学习IdentityServer3 (5)

    这篇文章介绍下数据持久化问题,官方例子可能都是缓存数据 Client  User Scope 下面介绍下怎么使用数据库持久化 这里需要导入nuget包 :IdentityServer3.EntityF ...

  10. shuffle过程分析

    shuffle的过程分析 shuffle阶段其实就是之前<MapReduce的原理及执行过程>中的步骤2.1.多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点 ...