「NOI2005」维护数列
「NOI2005」维护数列
传送门
维护过程有点像线段树。
但我们知道线段树的节点并不是实际节点,而平衡树的节点是实际节点。
所以在向上合并信息时要加入根节点信息。
然后节点再删除后编号要回退(栈),不然会爆空间。
具体实现看代码就好了。
参考代码:
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 1e6 + 2;
int tot, tmp[_];
int n, q, rt, siz[_], pri[_], ch[2][_];
int val[_], mx[_], L[_], R[_], sum[_], rev[_], tag[_], flag[_];
inline int Newnode(int v) {
int id = tmp[tot--];
siz[id] = 1, pri[id] = rand();
val[id] = mx[id] = sum[id] = v, L[id] = R[id] = max(0, v);
ch[0][id] = ch[1][id] = rev[id] = flag[id] = 0;
return id;
}
inline void pushup(int p) {
siz[p] = siz[ch[0][p]] + siz[ch[1][p]] + 1;
sum[p] = sum[ch[0][p]] + sum[ch[1][p]] + val[p];
L[p] = max(0, max(L[ch[0][p]], sum[ch[0][p]] + val[p] + L[ch[1][p]]));
R[p] = max(0, max(R[ch[1][p]], sum[ch[1][p]] + val[p] + R[ch[0][p]]));
mx[p] = max(val[p], R[ch[0][p]] + val[p] + L[ch[1][p]]);
if (ch[0][p]) mx[p] = max(mx[p], mx[ch[0][p]]);
if (ch[1][p]) mx[p] = max(mx[p], mx[ch[1][p]]);
}
inline void Rev(int p) {
rev[p] ^= 1, swap(L[p], R[p]), swap(ch[0][p], ch[1][p]);
}
inline void Tag(int p, int v) {
flag[p] = 1, val[p] = tag[p] = v, sum[p] = siz[p] * v;
L[p] = R[p] = max(0, sum[p]), mx[p] = max(val[p], sum[p]);
}
inline void pushdown(int p) {
if (rev[p]) {
if (ch[0][p]) Rev(ch[0][p]);
if (ch[1][p]) Rev(ch[1][p]);
rev[p] = 0;
}
if (flag[p]) {
if (ch[0][p]) Tag(ch[0][p], tag[p]);
if (ch[1][p]) Tag(ch[1][p], tag[p]);
flag[p] = 0;
}
}
inline int merge(int x, int y) {
if (!x || !y) return x + y;
if (pri[x] > pri[y])
return pushdown(x), ch[1][x] = merge(ch[1][x], y), pushup(x), x;
else
return pushdown(y), ch[0][y] = merge(x, ch[0][y]), pushup(y), y;
}
inline void split(int p, int k, int& x, int& y) {
if (p) pushdown(p);
if (!p) { x = y = 0; return ; }
if (siz[ch[0][p]] + 1 <= k)
return x = p, split(ch[1][p], k - siz[ch[0][p]] - 1, ch[1][x], y), pushup(p);
else
return y = p, split(ch[0][p], k, x, ch[0][y]), pushup(p);
}
inline void erase(int p) {
if (!p) return ;
tmp[++tot] = p;
if (ch[0][p]) erase(ch[0][p]);
if (ch[1][p]) erase(ch[1][p]);
}
int main() {
srand((unsigned long long) new char);
read(n), read(q);
for (rg int i = 1; i <= 500000; ++i) tmp[++tot] = i;
for (rg int v, i = 1; i <= n; ++i) read(v), rt = merge(rt, Newnode(v));
char s[15];
for (int pos, x, v, a, b, c; q--; ) {
scanf("%s", s);
if (s[0] == 'I') {
read(pos), read(x);
split(rt, pos, a, b);
while (x--) read(c), a = merge(a, Newnode(c));
rt = merge(a, b);
}
if (s[0] == 'D') {
read(pos), read(x);
split(rt, pos - 1, a, b);
split(b, x, b, c);
erase(b);
rt = merge(a, c);
}
if (s[0] == 'M' && s[2] == 'K') {
read(pos), read(x), read(v);
split(rt, pos - 1, a, b);
split(b, x, b, c);
Tag(b, v);
rt = merge(a, merge(b, c));
}
if (s[0] == 'R') {
read(pos), read(x);
split(rt, pos - 1, a, b);
split(b, x, b, c);
Rev(b);
rt = merge(a, merge(b, c));
}
if (s[0] == 'G') {
read(pos), read(x);
split(rt, pos - 1, a, b);
split(b, x, b, c);
printf("%d\n", sum[b]);
rt = merge(a, merge(b, c));
}
if (s[0] == 'M' && s[2] == 'X')
printf("%d\n", mx[rt]);
}
return 0;
}
「NOI2005」维护数列的更多相关文章
- 【NOI2005】维护数列
https://daniu.luogu.org/problem/show?pid=2042 一道伸展树维护数列的很悲伤的题目,共要维护两个标记和两个数列信息,为了维护MAX-SUM还要维护从左端开始的 ...
- ☆ [ZJOI2006] 书架 「平衡树维护数列」
题目类型:平衡树 传送门:>Here< 题意:要求维护一个数列,支持:将某个元素置顶或置底,交换某元素与其前驱或后继的位置,查询编号为\(S\)的元素的排名,查询排名第\(k\)的元素编号 ...
- 数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列
339. [NOI2005] 维护数列 时间限制:3 s 内存限制:256 MB [问题描述] 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际 ...
- [NOI2005] 维护数列
[NOI2005] 维护数列 题目 传送门 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 操作编号 输入文件中的格式 说明 1 ...
- P2042 [NOI2005]维护数列 && Splay区间操作(四)
到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...
- 洛谷 P2042 [NOI2005]维护数列-Splay(插入 删除 修改 翻转 求和 最大的子序列)
因为要讲座,随便写一下,等讲完有时间好好写一篇splay的博客. 先直接上题目然后贴代码,具体讲解都写代码里了. 参考的博客等的链接都贴代码里了,有空再好好写. P2042 [NOI2005]维护数列 ...
- 「BZOJ1485」[HNOI2009] 有趣的数列 (卡特兰数列)
「BZOJ1485」[HNOI2009] 有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai ...
- P2042 [NOI2005]维护数列[splay或非旋treap·毒瘤题]
P2042 [NOI2005]维护数列 数列区间和,最大子列和(必须不为空),支持翻转.修改值.插入删除. 练码力的题,很毒瘤.个人因为太菜了,对splay极其生疏,犯了大量错误,在此记录,望以后一定 ...
- Luogu P2042 [NOI2005]维护数列(平衡树)
P2042 [NOI2005]维护数列 题意 题目描述 请写一个程序,要求维护一个数列,支持以下\(6\)种操作:(请注意,格式栏中的下划线'_'表示实际输入文件中的空格) 输入输出格式 输入格式: ...
随机推荐
- iframe内外的操作
因为iframe涉及到跨域问题,有时候有的比较多,这不今天遇到了一个问题,处在iframe里头的js要操作iframe元素,查找百度,是可以实现的: 用jQuery在IFRAME里取得父窗口的某个元素 ...
- 1011 World Cup Betting
Title:1011 World Cup Betting 1. 注意点 比较简单,没有注意点 2. python3代码 def func(output): max = 0 index = -1 lin ...
- selenium+python实现自动化登录
工作需要实现一个微博自动登录的操作,在网上差了一些资料,决定使用selenium+python实现 selenium 是一个web的自动化测试工具,主流一般配合java或者python使用,我这里使用 ...
- 跨域-CORS
跨域:是浏览器为了安全而做出的限制策略 浏览器请求必须遵循同源策略:同域名,同端口,同协议 cors跨域- 服务器端设置,前端直接调用 说明:后台允许前端某个站点进行访问 后台设置 Access-Co ...
- Fluent_Python_Part2数据结构,02-array-seq,序列类型
1. 序列数据 例如字符串.列表.字节序列.元组.XML元素.数据库查询结果等,在Python中用统一的风格去处理.例如,迭代.切片.排序.拼接等. 2. 容器序列与扁平序列 容器序列:容器对象包含任 ...
- 安卓开发:Password verification failed
2019年8月5日更新: 我把Android Studio升级到3.4.2版本后,发现下图中的按钮已经不见了,所以本文中之前的创建签名文件的方法已经不行了- ...3.4.2版本是这样的---> ...
- beyond compare 用法
1.过滤器用法:点击小眼睛(回话-->回话设置)打开过滤器界面----设置多个过滤文件或目录直接使用回车键 2.比较时最好先设置编码以防出现乱码问题 工具-->文件格式. 3.比较时出现乱 ...
- EXPOSE ocker run -P 时,会自动随机映射 EXPOSE 的端口
EXPOSE 声明端口 格式为 EXPOSE <端口1> [<端口2>...]. EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用 ...
- CSS的精灵技术
- Build ear package
build 单个service ear TestService -> TestService 修改file Location地址(放在你指定的位置) 点击Build Archive succes ...