POJ3580 SuperMemo
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
Solution
能整合的操作大部分都整合了...所以这是个毒瘤题(码农题),不过维修序列貌似比这题更恐怖。
这题要求资瓷区间加,区间反转,区间旋转(其实就是从中间断开然后左右交换位置),单点插入,单点删除,区间查询最小值。
这些都能用fhqtreap解决。
区间加(和线段树),区间反转(^=1,交换左右子树)都打标记就行了,分裂合并的时候下传标记。其实就是码码码,没有别的...
然后注意一个坑就是poj的g++不资瓷time函数,我因为这个查了1h一直以为哪里写挂了,然后换成某八位质数就过了...(换成c++提交也没事...)
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <queue>
using namespace std;
#define N 500010
#define lc (t[rt].l)
#define rc (t[rt].r)
inline void in(int &x) {
x = 0; int f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= f;
}
const int inf = 1e9+1;
int n, m, root, tot;
struct fhq { int flag, l, r, siz, rnd, val, mn, tag; } t[N];
void rev(int rt) { t[rt].flag ^= 1; swap(lc, rc); }
void addone(int rt, int c) {
if(!rt) return;
t[rt].val += c; t[rt].mn += c; t[rt].tag += c;
}
void up(int rt) {
if(!rt) return;
t[rt].mn = min(t[rt].val, min(t[lc].mn, t[rc].mn));
t[rt].siz = 1 + t[lc].siz + t[rc].siz;
}
void down(int rt) {
if(!rt) return;
if(t[rt].tag) addone(lc, t[rt].tag), addone(rc, t[rt].tag);
if(t[rt].flag) rev(lc), rev(rc);
t[rt].tag = t[rt].flag = 0;
}
void split(int rt, int &l, int &r, int k) {
if(!k) l = 0, r = rt;
else if(k == t[rt].siz) l = rt, r = 0;
else if(k <= t[lc].siz) down(r=rt), split(lc, l, lc, k), up(rt);
else down(l=rt), split(rc, rc, r, k - t[lc].siz - 1), up(rt);
}
void merge(int &rt, int l, int r) {
if(!l || !r) rt = l + r;
else if(t[l].rnd < t[r].rnd) down(rt=l), merge(rc, rc, r), up(rt);
else down(rt=r), merge(lc, l, lc), up(rt);
}
int build(int x) {
t[++tot].rnd = rand()<<15|rand();
t[tot].siz = 1;
t[tot].val = t[tot].mn = x;
return tot;
}
void add(int l, int r, int c) {
int x, y, tmp;
split(root, x, y, r); split(x, x, tmp, l - 1);
addone(tmp, c);
merge(x, x, tmp); merge(root, x, y);
}
void reverse(int l, int r) {
int x, y, tmp;
split(root, x, y, r); split(x, x, tmp, l - 1);
rev(tmp);
merge(x, x, tmp); merge(root, x, y);
}
void del(int k) {
int x, y, tmp;
split(root, x, y, k); split(x, x, tmp, k - 1);
merge(root, x, y);
}
void insert(int k, int v) {
int x, y;
split(root, x, y, k); int tmp = build(v);
merge(x, x, tmp); merge(root, x, y);
}
void revolve(int l, int r, int v) {
int x, y, tmp, z;
split(root, x, y, r-v); split(y, z, y, v);
split(x, x, tmp, l-1);
merge(tmp, z, tmp); merge(x, x, tmp); merge(root, x, y);
}
int query(int l, int r) {
int x, y, tmp;
split(root, x, y, r); split(x, x, tmp, l - 1);
int ans = t[tmp].mn;
merge(x, x, tmp); merge(root, x, y);
return ans;
}
int main() {
srand((unsigned)time(0)); in(n);
t[0].mn = t[0].val = t[0].rnd = inf;
for(int i = 1, x; i <= n; ++i) {
in(x);
merge(root, root, build(x));
}
in(m);
for(int i = 1; i <= m; ++i) {
int l, r, v; char ch[20];
scanf("%s", ch);
if(ch[0] == 'A') in(l), in(r), in(v), add(l, r, v);
else if(ch[0] == 'R' && ch[3] == 'E') in(l), in(r), reverse(l, r);
else if(ch[0] == 'R' && ch[3] == 'O') in(l), in(r), in(v), revolve(l, r, v%(r-l+1));
else if(ch[0] == 'I') in(l), in(v), insert(l, v);
else if(ch[0] == 'D') in(l), del(l);
else in(l), in(r), printf("%d\n", query(l, r));
}
return 0;
}
POJ3580 SuperMemo的更多相关文章
- poj3580 SuperMemo (Splay+区间内向一个方向移动)
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13550 Accepted: 4248 Case Time Limit: ...
- POJ3580 SuperMemo splay伸展树,区间操作
题意:实现一种数据结构,支持对一个数列的 6 种操作:第 x 个数到第 y 个数之间的数每个加 D:第 x 个数到第 y 个数之间全部数翻转:第 x 个数到第 y 个数之间的数,向后循环流动 c 次, ...
- splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)
先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】
平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是 ...
- fhqtreap初探
介绍 fhqtreap为利用分裂和合并来满足平衡树的性质,不需要旋转操作的一种平衡树. 并且利用函数式编程可以极大的简化代码量. (题目是抄唐神的来着) 核心操作 (均为按位置分裂合并) struct ...
- 三大平衡树(Treap + Splay + SBT)总结+模板[转]
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 三大平衡树(Treap + Splay + SBT)总结+模板
Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...
- 【POJ3580】【splay版】SuperMemo
Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant i ...
随机推荐
- PHP运行脚本
PHP运行脚本 php.exe -f "php文件" php.exe -r "php代码" 例如:在cmd中 C:\Users\Administrator.SK ...
- 更换tomcat运行日志目录
1.在tomcat安装文件夹的bin目录下,修改catalina.sh,改变catalina.out的输出目录 CATALINA_OUT="$CATALINA_BASE"/logs ...
- [openjudge-搜索]广度优先搜索之鸣人和佐助
题目描述 描述 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸 ...
- vm无法删除干净老版本,新版本无法安装解决
百度中搜索“Windows Installer Clean UP 简体中文版”来下载安装好 开始程序,打开此软件, 找到vm,点remove 再次安装vm新版本,ok
- js中使用0 “” null undefined {}需要注意
注意:在js中0为空(false) ,代表空的还有“”,null ,undefined: 如果做判断if(!上面的四种值):返回均为false console.log(!null);// true c ...
- 怎样从外网访问内网WampServer?
本地安装了一个WampServer,只能在局域网内访问,怎样从外网也能访问到本地的WampServer呢?本文将介绍具体的实现步骤. 准备工作 安装并启动WampServer 默认安装的WampSer ...
- Oracle之数据库的增删改查和格式的修改
Oracle修改数据 *update语句 格式: update table_name set column1=value1,…[where conditions] 例子: update userinf ...
- MySQL笔记(八)存储过程练习&补充
存储过程有什么优缺点?为什么要用存储过程?或者在什么情况下才用存储过程? 最直白的好处是存储过程比较快. 1.利用存储过程,给Employee表添加一条业务部门员工的信息. DROP PROCEDUR ...
- kivy 小demo
from kivy.lang.builder import Builder from kivy.uix.boxlayout import BoxLayout from kivy.app import ...
- torchvision.datasets.ImageFolder数据加载
ImageFolder 一个通用的数据加载器,数据集中的数据以以下方式组织 root/dog/xxx.png root/dog/xxy.png root/dog/xxz.png root/cat/12 ...