非旋转 Treap 学习笔记(二)
来源:互联网 发布:js obj动态添加key 编辑:程序博客网 时间:2024/05/29 03:44
非旋转 Treap 学习笔记(一) 没有涉及一些区间的操作只是最基本的 Treap 操作,这篇才是非旋 Treap 真正优秀的地方。
要注意涉及区间操作时插入就是按照位置插入的,而不是按照权值的排名插入了。
Luogu P3391 【模板】文艺平衡树(Splay)
插入的时候分离前 pos - 1
个。
比如 1 2 3 4 5,在第 3 个位置插入一个 8,变成 1 2 8 3 4 5
把前面 1 2 分裂出来,后面 3 4 5 分裂出来
将 1 ~ n
分为 1 ~ (l - 1), l ~ r, (r + 1) ~ n
找到要翻转的区间 l ~ r
并标记。
在 pushDown 时翻转,就是将标记的节点 v 的左右子树交换,并不断将标记下传。
每次在 split 和 merge 的时候记得 pushDown。
最后 dfs 中序遍历一次求出最终翻转后的数列。
#include <bits/stdc++.h>using namespace std;const int N = 1e5 + 5;struct Treap { struct Node { Node *lc, *rc; int x, size, key; bool rev; Node(int x) : lc(NULL), rc(NULL), x(x), size(1), key(rand() * rand() * rand()), rev(false) {} inline void reverse() { rev ^= 1; } inline void pushDown() { if (rev) { swap(lc, rc); if (lc) lc->reverse(); if (rc) rc->reverse(); rev = false; } } inline void maintain() { size = (lc ? lc->size : 0) + (rc ? rc->size : 0) + 1; } inline int lSize() { return lc ? lc->size : 0; } } *root; /*int lowerCount(int x) { Node *v = root; int res = 0; while (v) { v->pushDown(); if (x <= v->x) v = v->lc; else res += v->lSize() + 1, v = v->rc; } return res; } int upperCount(int x) { Node *v = root; int res = 0; while (v) { v->pushDown(); if (x < v->x) v = v->lc; else res += v->lSize() + 1, v = v->rc; } return res; }*/ inline void split(Node *v, int k, Node *&l, Node *&r) { if(!v) { l = r = NULL; return ; } v->pushDown(); int s = v->lSize(); if(k <= s) { split(v->lc, k, l, r); v->lc = r; r = v; } else { split(v->rc, k - s - 1, l, r); v->rc = l; l = v; } v->maintain(); } Node *merge(Node *a, Node *b) { if (!a && !b) return NULL; if (!a) { b->maintain(); return b; } // if (!b) { a->maintain(): return a; } a->pushDown(); b->pushDown(); if (a->key > b->key) { a->rc = merge(a->rc, b); a->maintain(); return a; } else { b->lc = merge(a, b->lc); b->maintain(); return b; } } inline void insert(int pos, int x) { Node *pred, *tmp; split(root, pos - 1, pred, tmp); Node *v = new Node(x); root = merge(pred, merge(v, tmp)); } bool reverse(int l, int r) { Node *pred, *tmp; split(root, l - 1, pred, tmp); Node *target, *succ; split(tmp, r - l + 1, target, succ); target->reverse(); root = merge(pred, merge(target, succ)); } void dfs(Node *v, int *&p) { if (!v) return ; v->pushDown(); dfs(v->lc, p); *p ++ = v->x; dfs(v->rc, p); } void fetch(int a[]) { // p 是引用,会在整个递归过程中改变 int *p = &a[1]; dfs(root, p); }} treap;int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i ++) treap.insert(i, i); for (int i = 1; i <= m; i ++) { int l, r; scanf("%d%d", &l, &r); treap.reverse(l, r); } static int a[N]; treap.fetch(a); // 中序遍历一遍 for (int i = 1; i <= n; i ++) printf("%d%c", a[i], " \n"[i ==n]); return 0;}
阅读全文
0 0
- 非旋转 Treap 学习笔记(二)
- 非旋转 Treap 学习笔记(一)
- 可持久化(非旋转式)treap 学习记录
- bzoj 3224(非旋转treap)
- bzoj 3223(非旋转treap/splay)
- 非旋转treap模板
- 非旋转Treap
- 非旋转Treap-总结
- 【模板】非旋转Treap
- 非旋转treap模板
- 非旋转treap 模板
- 平衡树学习笔记——旋转式treap
- 非旋转treap模板(fhq treap)(洛谷3369,BZOJ3224)
- 【数据结构】范浩强Treap(非旋转平衡树)&可持久化Treap总结
- Treap模板(旋转)
- 【Treap/非旋转Treap】BZOJ3224 [Tyvj1728]普通平衡树
- 【Treap/非旋转Treap】BZOJ1503 [NOI2004]郁闷的出纳员
- 旋转式 treap 学习记录
- Selenium 自动化测试从零实战
- Ubuntu下安装opencv-3.3.0
- 各类模型参数汇总
- 【python 自然语言处理】对胡歌【猎场】电视剧评论进行情感值分析
- C#删除字符串最后一个字符的几种方法
- 非旋转 Treap 学习笔记(二)
- Linux系统介绍(一)命令行
- mysq免安装版l卸载过程相关问题
- iOS开发
- Deepo:几乎包含所有主流深度学习框架的Docker镜像
- Linux系统介绍(二)文件系统结构
- JAVA连接oracle中的表或视图
- Lambda表达式及相关练习
- !!! FAILED BINDER TRANSACTION !!!一旦遇上,便再也不想看见你