POJ 3580 SuperMemo 伸展树
题意:
维护一个序列,支持如下几种操作:
- ADD x y D:将区间\([x,y]\)的数加上\(D\)
- REVERSE x y:翻转区间\([x,y]\)
- REVOLVE x y T:将区间\([x,y]\)向右循环平移\(T\)个长度
- INSERT x P:在第\(x\)个元素后插入\(P\)
- DELETE x:删除第\(x\)个元素
- QUERY x y:查询区间\([x,y]\)中的最小值
分析:
ADD和REVERSE操作维护两个懒惰标记即可
REVOLVE操作本质还是CUT一段区间下来插入到别的位置(也可以REVERSE三次实现)
下面可以公开的情报:
经测试:数据的范围没有超过int,REVOLVE操作中的T没有负数,不要把add标记pushdown到null节点上,可能会溢出
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define PB push_back
#define PII pair<int, int>
#define REP(i, a, b) for(int i = a; i < b; i++)
#define PER(i, a, b) for(int i = b - 1; i >= a; i--)
#define ALL(x) x.begin(), x.end()
const int maxn = 100000 + 10;
const int INF = 0x3f3f3f3f;
int a[maxn];
struct Node {
Node* ch[2];
int s, v, minv;
bool flip; int add;
void maintain() {
minv = min(v, min(ch[0]->minv, ch[1]->minv));
s = ch[0]->s + ch[1]->s + 1;
}
int cmp(int k) {
k -= ch[0]->s + 1;
if(!k) return -1;
return k < 0 ? 0 : 1;
}
void pushdown();
};
int tot = 0;
Node pool[maxn << 1], *null;
void Node::pushdown() {
if(flip) {
flip = false;
swap(ch[0], ch[1]);
ch[0]->flip ^= 1;
ch[1]->flip ^= 1;
}
if(add) {
if(ch[0] != null) {
ch[0]->add += add;
ch[0]->v += add;
ch[0]->minv += add;
}
if(ch[1] != null) {
ch[1]->add += add;
ch[1]->v += add;
ch[1]->minv += add;
}
add = 0;
}
}
Node* newnode(int v) {
Node* p = pool + tot; tot++;
p->ch[0] = p->ch[1] = null;
p->s = 1; p->v = p->minv = v;
p->add = 0; p->flip = false;
return p;
}
void rotate(Node* &o, int d) {
Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d];
k->ch[d] = o; o->maintain(); k->maintain();
o = k;
}
void splay(Node* &o, int k) {
o->pushdown();
int d = o->cmp(k);
if(d == -1) return;
if(d == 1) k -= o->ch[0]->s + 1;
Node* &p = o->ch[d];
p->pushdown();
int d2 = o->ch[d]->cmp(k);
if(d2 == -1) { rotate(o, d^1); return; }
int k2 = k;
if(d2 == 1) k2 -= p->ch[0]->s + 1;
splay(p->ch[d2], k2);
if(d == d2) { rotate(o, d^1); rotate(o, d^1); }
else { rotate(p, d); rotate(o, d^1); }
}
void split(Node* o, int k, Node* &left, Node* &right) {
splay(o, k);
left = o;
right = o->ch[1];
left->ch[1] = null;
left->maintain();
}
Node* merge(Node* left, Node* right) {
splay(left, left->s);
left->ch[1] = right;
left->maintain();
return left;
}
Node* build(int l, int r) {
if(l > r) return null;
int mid = (l + r) / 2;
Node* p = newnode(a[mid]);
p->ch[0] = build(l, mid - 1);
p->ch[1] = build(mid + 1, r);
p->maintain();
return p;
}
void splayInit() {
tot = 0;
null = new Node;
null->ch[0] = null->ch[1] = null;
null->s = 0; null->v = null->minv = INF;
}
int main() {
int n, m;
while(scanf("%d", &n) == 1) {
splayInit();
a[0] = INF;
REP(i, 1, n + 1) scanf("%d", a + i);
Node* root = build(0, n);
scanf("%d", &m);
char cmd[10];
int x, y;
while(m--) {
scanf("%s%d", cmd, &x);
if(cmd[0] == 'A') {
int D; scanf("%d%d", &y, &D);
Node *o, *left, *mid, *right;
split(root, x, left, o);
split(o, y-x+1, mid, right);
mid->add += D;
mid->v += D;
mid->minv += D;
root = merge(merge(left, mid), right);
} else if(cmd[0] == 'R' && cmd[3] == 'E') {
scanf("%d", &y);
Node *o, *left, *mid, *right;
split(root, x, left, o);
split(o, y-x+1, mid, right);
mid->flip ^= 1;
root = merge(merge(left, mid), right);
} else if(cmd[0] == 'R' && cmd[3] == 'O') {
int T; scanf("%d%d", &y, &T);
int len = y - x + 1;
T %= len;
if(!T) continue;
T = y-x+1 - T;
Node *o, *left, *midl, *midr, *right;
split(root, x, left, o);
split(o, T, midl, o);
split(o, y-x+1-T, midr, right);
root = merge(merge(merge(left, midr), midl), right);
} else if(cmd[0] == 'I') {
int P; scanf("%d", &P);
Node* p = newnode(P), *left, *right;
split(root, x+1, left, right);
root = merge(merge(left, p), right);
} else if(cmd[0] =='D') {
Node* left, *mid, *right;
split(root, x, left, mid);
split(mid, 1, mid, right);
root = merge(left, right);
} else {
scanf("%d", &y);
Node* left, *mid, *right;
split(root, x, left, mid);
split(mid, y-x+1, mid, right);
printf("%d\n", mid->minv);
root = merge(merge(left, mid), right);
}
}
delete null;
}
return 0;
}
POJ 3580 SuperMemo 伸展树的更多相关文章
- POJ 3580 - SuperMemo - [伸展树splay]
题目链接:http://poj.org/problem?id=3580 Your friend, Jackson is invited to a TV show called SuperMemo in ...
- poj 3580 SuperMemo
题目连接 http://poj.org/problem?id=3580 SuperMemo Description Your friend, Jackson is invited to a TV sh ...
- Splay树(多操作)——POJ 3580 SuperMemo
相应POJ题目:点击打开链接 SuperMemo Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11309 Accept ...
- 平衡树(Splay):Splaytree POJ 3580 SuperMemo
SuperMemo Description Your friend, Jackson is invited to a TV show called SuperMemo in which ...
- POJ 3580 SuperMemo (splay tree)
SuperMemo Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6841 Accepted: 2268 Case Ti ...
- POJ 3580 SuperMemo (FHQ_Treap)
题意:让你维护一个序列,支持以下6种操作: ADD x y d: 第x个数到第y个数加d . REVERSE x y : 将区间[x,y]中的数翻转 . REVOLVE x y t :将区间[x,y] ...
- poj_3580 伸展树
自己伸展树做的第一个题 poj 3580 supermemo. 题目大意 对一个数组进行维护,包含如下几个操作: ADD x, y, d 在 A[x]--A[y] 中的每个数都增加d REVERSE ...
- 伸展树Splay
新学的,其实吧,就那么回事.... 看了几天,splay处理序列问题,真的非常厉害,翻转,插入,删除,线段树实现不了的功能,splay用起来很方便. POJ 3580 SuperMemo 这题基本就是 ...
- POJ 3580 (伸展树)
题目链接: http://poj.org/problem?id=3580 题目大意:对一个序列进行以下六种操作.输出MIN操作的结果. 解题思路: 六个操作,完美诠释了伸展树有多么吊.注意,默认使用L ...
随机推荐
- FinFET简介
什么是FET? FET 的全名是“场效电晶体(Field Effect Transistor,FET)”,先从大家较耳熟能详的“MOS”来说明.MOS 的全名是“金属-氧化物-半导体场效电晶体(Met ...
- System Center Configuration Manager 2016 必要条件准备篇(Part3)
步骤3.安装SQL Server 2017 注意:在Configuration Manager服务器(CM16)上以本地管理员身份执行以下操作 按照https://go.microsoft.com ...
- 用户管理的设计--4.jquery的ajax实现登录名的校验
页面效果 鼠标失去焦点时,不需要刷新页面进行校验,判断登录名是否重复. 实现步骤 1.引入struts2-json-plugin-2.5.10.1插件包 2.页面使用jquery的ajax实现后台校验 ...
- C语言中 fputs() fgets() 的使用方法
一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为: fgets(字符数组名,n,文件指针): 其中的n是一个正整数.表示从文件中读出的字符串不超过 n-1 ...
- Html : 规范html代码的网站
html代码的规范也是很重要的,这里推荐一个网站,很好用,仓鼠是经常用的啦! https://htmlformatter.com/ 以上
- 【js基础修炼之路】--创建文档碎片document.createDocumentFragment()
讲这个方法之前,我们应该先了解下插入节点时浏览器会做什么. 在浏览器中,我们一旦把节点添加到document.body(或者其他节点)中,页面就会更新并反映出这个变化,对于 ...
- POJ-2151 Check the difficulty of problems---概率DP好题
题目链接: https://vjudge.net/problem/POJ-2151 题目大意: ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 问 每队至少解出一题且冠军队至少解出N ...
- 类型构造器--高阶类型(构造器):Kind (type theory)--类型的元
元类型(0阶类型):nullary type, data types 一元类型(一阶类型):unary adj. [数] 一元的 二元类型: is the kind of a binary ty ...
- 类似LCS,构成目标单词(POJ2192)
题目链接:http://poj.org/problem?id=2192 解题报告: 1.类似最长公共子序列,dp[i][j]表示用s1前i个字符和s2前j个字符来构成目标单词的一部分,是否成功 2.状 ...
- cgi程序报 Premature end of script headers:
这段时间写了一个CGI,也是为了应付工作,挺简单的一个程序,总是在调用的时候报:Premature end of script headers: 很让人头疼! 在网上找了些资料,按资料 ---- ...