博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
序列终结者
阅读量:7045 次
发布时间:2019-06-28

本文共 2604 字,大约阅读时间需要 8 分钟。

Description

维护一个序列,支持区间加,区间翻转,区间取最大值这三个操作。

Solution

Splay.

就是细节比较麻烦。

Code

#include 
#include
const int N = 50000 + 10; int fa[N], ch[N][2], val[N], sz[N], rev[N], add[N], mx[N]; void upd(int x) { sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1; mx[x] = std::max(val[x], std::max(mx[ch[x][0]], mx[ch[x][1]]));}void pd(int x) { if (rev[x]) { std::swap(ch[x][0], ch[x][1]); rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; rev[x] = 0; } if (add[x]) { if (ch[x][0]) val[ch[x][0]] += add[x], add[ch[x][0]] += add[x], mx[ch[x][0]] += add[x]; if (ch[x][1]) val[ch[x][1]] += add[x], add[ch[x][1]] += add[x], mx[ch[x][1]] += add[x]; add[x] = 0; }}int dir(int x) { return x == ch[fa[x]][1]; }void rot(int x) { int f = fa[x], d = dir(x); if (fa[x] = fa[f]) ch[fa[x]][dir(f)] = x; if (ch[f][d] = ch[x][d^1]) fa[ch[f][d]] = f; ch[fa[f] = x][d^1] = f; upd(f); upd(x);}int st[N];void splay(int x, int t = 0) { int top = 0, i; for (i = x; fa[i]; i = fa[i]) st[top++] = fa[i]; while (top--) pd(st[top]); pd(x); for (; fa[x] != t; rot(x)) if (fa[fa[x]] != t) rot(dir(fa[x]) == dir(x) ? fa[x] : x);}int kth(int k, int t) { int o = t; while (1) { pd(o); if (sz[ch[o][0]] == k-1) break; else if (sz[ch[o][0]] >= k) o = ch[o][0]; else { k -= sz[ch[o][0]] + 1; o = ch[o][1]; } } splay(o, fa[t]); return o;}int n;void reverse(int l, int r) { splay(1); int y = kth(r+1, 1); int x = ch[y][0]; kth(l-1, x); rev[ch[ch[y][0]][1]] ^= 1;}void addval(int l, int r, int k) { splay(1); int y = kth(r+1, 1); int x = ch[y][0]; kth(l-1, x); add[ch[ch[y][0]][1]] += k; val[ch[ch[y][0]][1]] += k; mx[ch[ch[y][0]][1]] += k;}int query(int l, int r) { splay(1); int y = kth(r+1, 1); int x = ch[y][0]; kth(l-1, x); return mx[ch[ch[y][0]][1]];} void put(int o) { if (!o) return; put(ch[o][0]); printf("%d %d %d\n", ch[o][0], ch[o][1], val[o]); put(ch[o][1]); } int main() { scanf("%d", &n); for (int i = 1; i <= n+2; ++i) { if (fa[i] = i-1) ch[i-1][1] = i; sz[i] = n - i + 3; val[i] = 0; } mx[0] = -2147483647; val[n+1] = 0; int m, l, r, v, op; scanf("%d", &m); while (m--) { scanf("%d%d%d", &op, &l, &r); if (op == 1) { scanf("%d", &v); addval(l+1, r+1, v); } else if (op == 2) reverse(l+1, r+1); else printf("%d\n", query(l+1, r+1)); } return 0;}

Note

如果不是非常必要的话,还是不要使用平衡树了,实在是有点难调,也没有线段树直观。

转载于:https://www.cnblogs.com/wyxwyx/p/bzoj1251.html

你可能感兴趣的文章
IsolatedStorageSettings存储数据_____简单_____自定义(复杂)____数据
查看>>
《敏捷软件开发》第4章测试
查看>>
DOS windows 使用bat脚本获取 IP MAC 系统信息
查看>>
PHP给图片添加水印
查看>>
Yaf学习(三)----Yaf类库Library和Model的命名规则
查看>>
蓝桥学院2019算法题2.1-2.5
查看>>
浅谈CLR CTS CLS。。。
查看>>
软件需求十步走读书笔记2
查看>>
[leetcode-647-Palindromic Substrings]
查看>>
UEditor
查看>>
nowcoder N约数个数
查看>>
Test a ; vs Test a( ) ;
查看>>
lemp(lnmp)web网站搭建
查看>>
【动态规划】Gym - 100507G - The Debut Album
查看>>
使用Redis+Flask维护动态代理池
查看>>
POJ 2594 - Treasure Exploration
查看>>
python的request包
查看>>
config配置中心之自动刷新
查看>>
杭电 1018 Big Number
查看>>
SQL Server的差异备份还原
查看>>