POJ 3468 Splay 解法
来源:互联网 发布:淘宝爆款打造花钱 编辑:程序博客网 时间:2024/05/02 19:45
题解
Splay入门模板
将l - 1移到根, r + 1移到根下方, 那么[l, r]就在根的右子树的左子树上, 更新的时候也这样旋转, 更新lazy
code:
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define debug 0#define M(a, b) memset(a, b, sizeof(a))#define ls ch[x][0]#define rs ch[x][1]const int maxn = (1e5 + 10);struct Splay{ int pre[maxn], ch[maxn][2], sz[maxn], v[maxn]; int add[maxn], a[maxn]; int root, rt; long long sum[maxn]; Splay() { root = rt = 0; M(pre, 0); M(ch, 0); M(sz, 0); M(v, 0); M(sum, 0); M(add, 0); } void newNode(int &x, int c) {//新建节点 x = ++rt; sz[x] = 1; v[x] = sum[x] = c; } void pushDown(int x) {//下移 if (add[x]) { v[x] += add[x]; add[ls] += add[x]; add[rs] += add[x]; sum[ls] += (long long)sz[ls] * add[x]; sum[rs] += (long long )sz[rs] * add[x]; add[x] = 0; } } void pushUp(int x) {//向上传递 sz[x] = sz[ls] + sz[rs] + 1; sum[x] = sum[ls] + sum[rs] + v[x]; } void Rotate(int x, int d) {//旋转 int y = pre[x]; pushDown(y); pushDown(x); ch[y][!d] = ch[x][d]; pre[ch[y][!d]] = y; pre[x] = pre[y]; ch[x][d] = y; if (pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x; pre[y] = x; pushUp(y); } void splay(int x, int to) {//转到 while (pre[x] != to) { if (pre[pre[x]] == to) Rotate(x, ch[pre[x]][0] == x); else { int y = pre[x], z = pre[y]; int f = (ch[z][1] == y); if (ch[y][f] == x) Rotate(y, !f), Rotate(x, !f); else Rotate(x, f), Rotate(x, !f); } } pushUp(x); if (!to) root = x; } void RotateTo(int k, int to) { int x = root; pushDown(x); while (sz[ls] != k) { if (sz[ls] < k) { k -= sz[ls] + 1; x = rs; } else { x = ls; } pushDown(x);//要旋转在查找时要下移 } splay(x, to); } void build(int &x, int l, int r, int f) { if (l > r) return; int mid = (l + r) >> 1; newNode(x, a[mid]); build(ls, l, mid - 1, x); build(rs, mid + 1, r, x); pre[x] = f; pushUp(x); } void init(int n) { newNode(root, -1);//加两个节点, 去除冗余信息 newNode(ch[root][1], -1); pre[rt] = root; sz[root] = 2; for (int i = 0; i < n; ++i) scanf("%d", &a[i]); build(ch[ch[root][1]][0], 0, n - 1, ch[root][1]);//建树, 保证中序遍历一致 pushUp(ch[root][1]);//传递 pushUp(root); } void update(int l, int r, int val) { RotateTo(l - 1, 0); RotateTo(r + 1, root); add[ch[ch[root][1]][0]] += val; sum[ch[ch[root][1]][0]] += (long long )val * sz[ch[ch[root][1]][0]];//[l, r]lazy } long long query(int l, int r) { RotateTo(l - 1, 0); RotateTo(r + 1, root); return sum[ch[ch[root][1]][0]]; }}sp;int main() {#if debug freopen("in.txt", "r", stdin);#endif //debug //cin.tie(0); //cin.sync_with_stdio(false); int n, m, l, r, c; char s[5]; while (~scanf("%d%d", &n, &m)) { sp.init(n); while (m--) { scanf("%s%d%d", s, &l, &r); if (s[0] == 'Q') printf("%I64d\n", sp.query(l, r)); else { scanf("%d", &c); sp.update(l, r, c); } } } return 0;}
0 0
- POJ 3468 Splay 解法
- poj 3468 A Simple Problem with Integers(splay tree解法)
- POJ 3468 splay
- poj 3468 Splay 树
- poj 3468 splay入门
- POJ 3468 Splay 做法
- POJ 3468 splay
- poj 3667 Hotel(线段树区间合并&Splay解法)
- poj 3468 树状数组解法
- poj 3468 树状数组解法
- poj 3468 Splay Tree 区间操作
- poj 3468(线段树,splay tree)
- Splay-tree poj 3580
- poj 3580 splay tree
- poj 2761 splay tree
- splay POJ 3580SuperMemo
- POJ 3580 SuperMemo(Splay)
- POJ 3580 SuperMemo(Splay)
- iOS屏幕旋转
- 关于记忆化搜索
- 搭建高可用mongodb集群(四)—— 分片
- ionic android mac 环境配置
- webSocket获取HttpSession
- POJ 3468 Splay 解法
- Leetcode在线编程reorder-list
- 初探Linux——内核编译
- 【9604】纪念品分组
- cassandra 、mongodb、mariadb集群总结
- 显示网格(grid)
- python字典的练习使用
- 【心情】bjdldrz
- webSocket入门java实现