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

【分析】
真实蛋疼了。。
第一次写的时候居然犯了一个傻逼到极点的错误。。。。
翻转部分不会,是看别人的。不过感觉应该还有不同的写法。
代码写得比较丑,主要是尝试了引用。
 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#define LOCAL
const int MAXN = + ;
const int INF = ;
const int SIZE = ;
const int maxnode = 0x7fffffff + ;
using namespace std;
struct SPLAY{
struct Node{
int val, Min;//分别为值,最小值,大小和lazy下标
int size, lazy;
bool turn;
Node *parent, *ch[]; //初始化
void NEW(int x){
Min = val = x;
size = ;
lazy = turn = ;
parent = ch[] = ch[] = NULL;
}
int cmp(){
if (parent->ch[] == this) return ;
if (parent->ch[] == this) return ;
}
//还是不要写在里面了..
/*void pushdown(){ }
void update(){
size = 1;
if (x->ch[0] != NULL) size += x->ch[0]->size;
if (x->ch[1] != NULL) size += x->ch[0]->size;
}
*/
}mem[MAXN], *root;//mem为静态数组
int tot; int get(Node *&x){return (x == NULL ? : x->size);}
//————————————————————这一部分不能卸载里面
//更新
void update(Node *&x){
if (x == NULL) return;
x->size = ;
x->Min = x->val;
if (x->ch[] != NULL) {x->Min = min(x->Min, x->ch[]->Min);x->size += x->ch[]->size;}
if (x->ch[] != NULL) {x->Min = min(x->Min, x->ch[]->Min);x->size += x->ch[]->size;}
}
void pushdown(Node *&x){//标记下传
if (x == NULL) return;
if (x->lazy){
int tmp = x->lazy;
x->val += tmp;
if (x->ch[] != NULL) {x->ch[]->lazy += tmp;x->ch[]->Min += tmp;}
if (x->ch[] != NULL) {x->ch[]->lazy += tmp;x->ch[]->Min += tmp;}
x->lazy = ;
}
if (x->turn){//翻转
swap(x->ch[], x->ch[]);//swap内部用什么实现的呢? if (x->ch[] != NULL) x->ch[]->turn ^= ;
if (x->ch[] != NULL) x->ch[]->turn ^= ;
x->turn = ;
}
} //————————————————————————————
//旋转,1为右旋, 0为左旋
void Rotate(Node *&x, int d){//不用引用也可以
Node *y = x->parent;
pushdown(y);//注意顺序
pushdown(x);
pushdown(x->ch[d]);//这个不要忘了 y->ch[d ^ ] = x->ch[d];
if (x->ch[d] != NULL) x->ch[d]->parent = y;
x->parent = y->parent;
if (y->parent != NULL){
if (y->parent->ch[] == y) y->parent->ch[] = x;
else y->parent->ch[] = x;
}
x->ch[d] = y;
y->parent = x;
update(y);
if (y == root) root = x;//如果是引用要小心root被传下去
}
void debug(){
Node *p = new Node;
root = new Node;
root->ch[] = p;
p->parent = root;
printf("%d", p->cmp());
}
//注意我写的这个跟下午那个不一样,下午那个好麻烦
void splay(Node *&x, Node *&y){
pushdown(x);
while (x != y){
if(x->parent == y){
if (y->ch[] == x) Rotate(x, );
else Rotate(x,);
break;
}else{
Node *y = x->parent, *z = y->parent;//注意一定要这样弄一下
if (z->ch[] == y)
if (y->ch[] == x) Rotate(y,),Rotate(x, );
else Rotate(x, ), Rotate(x, );
else if (y->ch[] == x) Rotate(y, ), Rotate(x, );
else Rotate(x, ), Rotate(x, );
if (z == y) break;
}
update(x);
}
update(x);
}
//寻找第k大
void find(Node *&t, int k){
int tmp;
Node *p = root;
while (){
pushdown(p);
tmp = get(p->ch[]);
if (k == (tmp + )) break;
if (k <= tmp) p = p->ch[];
else {k -= tmp + , p = p->ch[];}
}
pushdown(p);
splay(p, t);
}
//插入操作
void Insert(int pos, int val){
//还是卡出来
find(root, pos + );
find(root->ch[], pos + );
Node *t = &mem[tot++], *x = root->ch[];
pushdown(root);
pushdown(x);
t->NEW(val);
//直接拆开放中间,放在root->ch[1]->ch[0]应该也可以
t->ch[] = x;
x->parent = t;
root->ch[] = t;
t->parent = root;
splay(x, root);
}
//区间加
void Add(int l, int r, int x){
find(root, l);
find(root->ch[] , r + );
Node *t = root->ch[]->ch[];
pushdown(t);
update(t);
t->Min += x;
t->lazy += x;
splay(t, root);
}
//翻转操作
void Reverse(int l, int r){
find(root, l);
find(root->ch[], r + );
root->ch[]->ch[]->turn ^= ;
Node *x = root->ch[]->ch[];
splay(x, root);
}
//交换操作,这一段我是看别人的....
void Revolve(int l, int r, int t){
Node *p1, *p2; find(root, l);
find(root->ch[], r + );
find(root->ch[]->ch[], r + - t); p1 = root->ch[]->ch[];
pushdown(p1);
p2 = p1->ch[];
p1->ch[] = NULL;
find(root->ch[]->ch[], l + );
p1 = root->ch[]->ch[];
pushdown(p1);
p1->ch[] = p2;
p2->parent = p1;
splay(p2, root);
}
int getMin(int l, int r){
find(root, l);
find(root->ch[], r + );
Node *x = root->ch[];
pushdown(x);
x = x->ch[];
pushdown(x);
update(x);
return x->Min;
}
void Erase(int pos){//删除
find(root, pos);
find(root->ch[], pos + );
pushdown(root->ch[]);
root->ch[]->ch[] = NULL;
Node *x = root->ch[];
splay(x, root);
}
void init(){
//注意还要加一个正无穷
tot = ;
root = &mem[tot++];
root->NEW(INF);
root->ch[] = &mem[tot++];
root->ch[]->NEW(INF);
}
void print(Node *t){
if (t == NULL) return;
print(t->ch[]);
printf("%d ", t->val);
if (t->parent != NULL) printf("%d\n", t->parent->val);
print(t->ch[]);
}
}A; int n, m;
//注意在这里为了防止掉到0,所以每个位置都要+1
void init(){//初始化
A.init();
scanf("%d", &n);
for (int i = ; i < n; i++){
int x;
scanf("%d", &x);
A.Insert(i, x);
//printf("%d\n", A.root->val);
}
//A.print(A.root);
}
void work(){
scanf("%d", &m);
for (int i = ; i <= m; i++){//询问,按顺序来。。
char str[];
scanf("%s", str);
if (str[] == 'A'){
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
A.Add(l, r, x);
}else if (str[] == 'R'){
int l, r;
scanf("%d%d", &l, &r);
if (str[] == 'E') A.Reverse(l, r);
else{
int x, len;
scanf("%d", &x);
len = r - l + ;
x = (x % len + len) % len;
if (x == || l == r) continue;//我开始居然傻逼的写在前面....
A.Revolve(l, r, x);
}
}else if (str[] == 'I'){
int l, x;
scanf("%d%d", &l, &x);
A.Insert(l, x);
}else if (str[] == 'D'){
int l;
scanf("%d", &l);
A.Erase(l);
}else if (str[] == 'M'){
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", A.getMin(l, r));
}
}
}
void debug(){ } int main(){ init();
work();
//debug();
//A.debug();
return ;
}

【POJ3580】【splay版】SuperMemo的更多相关文章

  1. poj3580 splay树 REVOVLE循环

    SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12795   Accepted: 3989 Case T ...

  2. [P3369]普通平衡树(Splay版)

    模板,不解释 #include<bits/stdc++.h> using namespace std; const int mxn=1e5+5; int fa[mxn],ch[mxn][2 ...

  3. bzoj1861 书架 splay版

    单点插入删除以及求前缀 #include<cstdio> #include<cstring> #include<algorithm> using namespace ...

  4. bzoj1503 郁闷的出纳员 splay版

    自己yy的写法 可能有点奇怪吧 详情看代码 还是蛮短的 #include<cstdio> #include<cstring> #include<algorithm> ...

  5. splay版

    指针是个好东西 不过就是得判空 还有别忘传引用(其实应该都传引用) #include<cstdio> #include<algorithm> #include<iostr ...

  6. AC日记——营业额统计 codevs 1296 (splay版)

    营业额统计 思路: 每次,插入一个点: 然后找前驱后继: 来,上代码: #include <cmath> #include <cstdio> #include <iost ...

  7. 数列[专杀Splay版]

    时间限制: 3 Sec  内存限制: 128 MB提交: 49  解决: 7 题目描述 输入一个数列,你需要进行如下操作:  1. 把编号为I的数值改为K  2. 输出从小到大排序后第k个数 输入 输 ...

  8. 牛客网多校训练第三场 C - Shuffle Cards(Splay / rope)

    链接: https://www.nowcoder.com/acm/contest/141/C 题意: 给出一个n个元素的序列(1,2,...,n)和m个操作(1≤n,m≤1e5),每个操作给出两个数p ...

  9. BZOJ2028:[SHOI2009]会场预约(平衡树版)

    浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...

随机推荐

  1. 【转】MFC窗口句柄各类指针获取函数

    原文网址:http://www.pythonschool.com/CPP_JHK/5003.html 获取所在类窗口的句柄 this->m_hwnd; // this是一个指针,指向当前类的实例 ...

  2. java Spring使用配置文件读取jdbc.properties

    Spring使用配置文件读取jdbc.properties 在beans.xml中加入两个必须的bean [html]<bean id="propertyConfigurer" ...

  3. iOS动态管理AutoLayout的约束NSLayoutConstraint

    除了使用Storyboard之外,也可以使用使用代码的方式,动态的向指定的UIView,添加约束. 例如有两个UILabel:someLabel,otherLabel 首先用代码实例化,两个控件 se ...

  4. phpmyadmin万能密码

    影响版本:2.11.3 / 2.11.4 利用方法:用户名处写入‘localhost’@'@”则登录成功. (注意全部是英文标点符号,最后一个为英文双引号)

  5. flash引入

    博客页面引入一个小人的动画时钟代码 <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase ...

  6. 2的32次方 分类: C#小技巧 2014-08-05 18:18 406人阅读 评论(0) 收藏

    版权声明:本文为博主原创文章,未经博主允许不得转载.

  7. 华为EC169在MAC 10.9.6下的安装方法

    [问题描述] 华为EC169 3G上网卡需要在mbp中安装驱动. 华为官网(http://consumer.huawei.com/cn/)直接搜索EC169,会发现最新的驱动也是2009年发布. 下载 ...

  8. Media Queries 自适应布局展示

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. HTML5事件——contextmenu 隐藏鼠标右键菜单

    在window中单击右键或在Mac中Ctrl+单击时会触发contextmenu事件,通过取消其默认动作能够提供自己定义菜单. 首先先写一个自己的菜单: <style> ul, li { ...

  10. mysql函数count(*)和count(column)的区别(转)

    mysql中count(*)和count(column)使用是有区别的: count(*)对行的数目进行计算,包含NULL count(column)对特定的列的值具有的行数进行计算,不包含NULL值 ...