「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;
}

最新文章

  1. DIV+CSS自适应布局
  2. Fiddler 抓包工具总结
  3. openldap主机访问控制(基于用户组)
  4. 采用get的方式提交数据到服务器
  5. Android要点记录
  6. Codeforces Round #223 (Div. 2) A
  7. PHPExcel读取excel的多个sheet存入数据库
  8. hadoop聚群的安装
  9. Qt模拟C#的File类对文件进行操作
  10. http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/
  11. android 自动化(1)
  12. mount命令以及mount ntfs硬盘权限权限与显示的问题 分类: shell ubuntu 2014-11-08 18:29 148人阅读 评论(0) 收藏
  13. UVA 1617 Laptop
  14. JAVA处理XML
  15. ThinkPHP 连接Oracle的配置写法,(使用Oci扩展而非PDO的写法)
  16. codeforces 651C Watchmen
  17. MySQL5.7 并行复制的学习
  18. C语言之一维数组与指针
  19. 10 Comparisons with adjectvies and nouns
  20. CentOS7.2卸载完CDH5.12后重装CDH

热门文章

  1. 干货 | C#开发的电影售票系统
  2. 【Go语言系列】第三方框架和库——GIN:快速入门
  3. PHP如何实现处理过期或者超时订单的,并还原库存
  4. VBA 学习笔记 - 消息框
  5. 例题3_3 回文词(UVa401)
  6. java 责任链模式的三种实现
  7. Spring Boot RestApi 测试教程 Mock 的使用
  8. 洛谷P1908 逆序对(线段树解法)
  9. Python语言——列表生成式
  10. C语言-数组与指针 字符与字符串