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 ...
随机推荐
- 《大话设计模式》c++实现 原型模式
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 主要解决:在运行期建立和删除原型. 何时使用: 1.当一个系统应该独立于它的产品创建,构成和表示时. 2.当要实例化的类是在运行 ...
- E. Bear and Drawing
E. Bear and Drawing time limit per test 1 second memory limit per test 256 megabytes input stan ...
- Qt 事件机制
[1]事件 事件是可以被控件识别的操作.如按下确定按钮.选择某个单选按钮或复选框. 每种控件有自己可识别的事件,如窗体的加载.单击.双击等事件,编辑框(文本框)的文本改变事件等等. 事件就是用户对窗口 ...
- JS实战
1. jquery取消点击事件 $("#dashboard").unbind("click"); 2.jquery绑定鼠标滑过,离开事件 $("#da ...
- redis启动
在redis的安装目录的bin目录下: 1.启动服务(指定配置文件) ./redis-server redis.conf 2.启动客户端 ./redis-cli
- 转:【专题四】自定义Web浏览器
前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...
- QThread详解
回顾Qt之线程(QThread),里面讲解了如何使用线程,但还有很多人留言没有看明白,那么今天我们来一起瞅瞅关于QThread管理线程的那些事儿... 一.线程管理 1.线程启动 void start ...
- [转载]dbms_lob用法小结
http://blog.sina.com.cn/s/blog_713978a50100prkt.html CLOB里存的是2进制 判定长度 DBMS_LOB.GETLENGTH(col1)获取文本 ...
- Linux下MySQL远程链接配置
配置步骤: 1).首先进入数据库,使用系统数据库mysql mysql -u root -p mysql 2).接着对系统数据库的root账户设置远程访问的密码,与本地的root访问密码并不冲突 gr ...
- 推荐:全新Java开发思维导图
蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力.培训.出国.大公司的经历,还有很多很好的朋友. 但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员,可 ...