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 ...
随机推荐
- linux常见运维题
linux运维题 一.填空题 1. 在Linux 系统 中,以文件方式访问设备 . (linux下一切都是文件) 2. Linux 内核引导时,从文件/etc/fstab中读取要加载的文件系统 . ( ...
- “编程利器”:VSCode
原先一直使用sublime text3,并且认为它是很好的编程利器. 但最近写代码时,发现很多代码还是提示的不够完整.我们知道,当代码名字很长时,还没有提醒,这是非常苦恼的一件事!同时它的调试功能也不 ...
- 【Hadoop学习之三】Hadoop全分布式安装
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop3.1.1 全分布式就是集群,注意配置主机名. ...
- Redis的key和value大小限制
Redis的key和value大小限制 今天研究了下将java bean序列化到redis中存储起来,突然脑袋灵光一闪,对象大小会不会超过redis限制?不管怎么着,还是搞清楚一下比较好 ...
- flask 表单
表单 在Web程序中,表单时和用户交互最常见的方式之一.用户注册.登录.撰写文章.编辑设置,无一不用到表单.不过,表单的处理不简单.要创建表单,验证用户输入的内容,向用户显示错误提示,还要获取并保存数 ...
- (Review cs231n) Gradient Calculation and Backward
---恢复内容开始--- 昨日之补充web. 求解下图的梯度的流动,反向更新参数的过程,表示为 输入与损失梯度的关系,借助链式法则,当前输入与损失之间的梯度关系为局部梯度乘以后一层的梯度. ---恢复 ...
- Linux基础命令---文本显示tac
tac 将指定文件中的行,按照反序方式显示.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法 tac [选项] ...
- TensorFire:WEB端的高性能神经网络框架
TensorFire:WEB端的高性能神经网络框架 摘要: 近日,一种专门用于在网页内执行神经网络算法的JavaScript库——TensorFire引起了人们的关注,这种JavaScript库在浏览 ...
- 2、在VM上的 CentOS 6.5 上安装mysql
1.查看系统是否安装了MySQL 使用命令: #rpm -qa | grep mysql 2.卸载已安装的MySQL 卸载mysql命令如下: #rpm -e - ...
- Qt发布可执行程序
在Qt Creator下用release跑一遍程序,生成相应的EXE文件. 在Qt Creator下编译好的release下的 youProgramName.exe 拷贝到一个文件夹下面: 在 ...