一:Treap

支持:插入、删除、查询 x x x 的排名、查询排名为 x x x 的数、查前驱、查后继、左旋右旋
模板题:P3369 【模板】普通平衡树

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int INF = 1e9 + 7;
const int maxn = 1e5 + 5;
int rt, tot;
int sz[maxn], val[maxn], cnt[maxn];
int rd[maxn], son[maxn][2];inline void pushup(int x) {sz[x] = sz[son[x][0]] + sz[son[x][1]] + cnt[x];
}
inline void rotate(int &x, int y) {int ii = son[x][y^1];son[x][y^1] = son[ii][y], son[ii][y] = x;pushup(x), pushup(ii), x = ii;
}
void ins(int &p, int x) {if(!p) {p = ++tot, sz[p] = cnt[p] = 1;val[p] = x, rd[p] = rand();return;}if(val[p] == x) return cnt[p]++, sz[p]++, void();int d = x > val[p]; ins(son[p][d], x);if(rd[p] < rd[son[p][d]]) rotate(p, d^1);pushup(p);
}
void del(int &p, int x) {if(!p) return;if(x != val[p]) del(son[p][x>val[p]], x);else {if(!son[p][0] && !son[p][1]) {cnt[p]--, sz[p]--;if(cnt[p] == 0) p = 0;} else if(son[p][0] && !son[p][1]) {rotate(p, 1), del(son[p][1], x);} else if(!son[p][0] && son[p][1]) {rotate(p, 0), del(son[p][0], x);} else {int d = rd[son[p][0]] > rd[son[p][1]];rotate(p, d), del(son[p][d], x);}}pushup(p);
}
int get_rank(int p, int x) {if(!p) return 0;if(val[p] == x) return sz[son[p][0]] + 1;if(val[p] < x) return sz[son[p][0]] + cnt[p] + get_rank(son[p][1], x);return get_rank(son[p][0], x);   // val[p]>x
}
int kth(int p, int x) {if(!p) return 0;if(sz[son[p][0]] >= x) return kth(son[p][0], x);else if(sz[son[p][0]] + cnt[p] < x) return kth(son[p][1], x-cnt[p]-sz[son[p][0]]);else return val[p];
}
int pre(int p, int x) {if(!p) return -INF;if(val[p] >= x) return pre(son[p][0], x);else return max(val[p], pre(son[p][1], x));
}
int suf(int p, int x) {if(!p) return INF;if(val[p] <= x) return suf(son[p][1], x);else return min(val[p], suf(son[p][0], x));
}signed main() {int Q;scanf("%d", &Q);while(Q--) {int opt, x;scanf("%d%d", &opt, &x);if(opt == 1) ins(rt, x);else if(opt == 2) del(rt, x);else if(opt == 3) printf("%d\n", get_rank(rt, x));else if(opt == 4) printf("%d\n", kth(rt, x));else if(opt == 5) printf("%d\n", pre(rt, x));else if(opt == 6) printf("%d\n", suf(rt, x));}
}

二:FHQ Treap

支持:按权值 v a l val val 分割(维护 v a l val val 的有序性)、按排名即 s i z e size size 分割(维护序列的有序性)、合并两颗树
      插入、删除、查询 x x x 的排名、查询排名为 x x x 的数、查前驱、查后继
      区间左移 —— HDU多校第九场 1007 Game —— 区间左移 + FHQ Treap

模板题:P3369 【模板】普通平衡树

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());struct Treap {const static int maxn = 1e5 + 5;int root, tot;int sz[maxn], val[maxn];int rd[maxn], son[maxn][2];void init() {fill(sz, sz+tot+1, 0);fill(son[0], son[0]+tot+1, 0);fill(son[1], son[1]+tot+1, 0);root = tot = 0;}Treap() {root = tot = 0;
//        srand(clock() + time(0));}inline void pushup(int x) {sz[x] = sz[son[x][0]] + sz[son[x][1]] + 1;}inline int new_node(int v) {sz[++tot] = 1, val[tot] = v, rd[tot] = rnd();return tot;}int merge(int x, int y) {if(!x || !y) return x + y;if(rd[x] < rd[y]) return son[x][1] = merge(son[x][1], y), pushup(x), x;else return son[y][0] = merge(x, son[y][0]), pushup(y), y;}void split_by_val(int now, int k, int &x, int &y) {if(!now) return x = y = 0, void();if(val[now] <= k) x = now, split_by_val(son[now][1], k, son[now][1], y);else y = now, split_by_val(son[now][0], k, x, son[now][0]);pushup(now);}void split_by_sz(int now, int k, int &x, int &y) {if(!now) return x = y = 0, void();if(sz[son[now][0]] >= k) y = now, split_by_sz(son[now][0], k, x, son[now][0]);else x = now, split_by_sz(son[now][1], k-sz[son[now][0]]-1, son[now][1], y);pushup(now);}void ins(int v) {int x, y; split_by_val(root, v, x, y);root = merge(merge(x, new_node(v)), y);}void del(int v) {int x, y, z; split_by_val(root, v, x, z);split_by_val(x, v-1, x, y);y = merge(son[y][0], son[y][1]);root = merge(merge(x, y), z);}inline int get_rank(int v) {int x, y, ret;split_by_val(root, v-1, x, y);ret = sz[x] + 1;root = merge(x, y);return ret;}inline int kth(int now, int k) {  //  查询排名while(true) {if(k <= sz[son[now][0]]) now = son[now][0];else if(k == sz[son[now][0]] + 1) return val[now];else k -= sz[son[now][0]] + 1, now = son[now][1];}}inline int pre(int v) {int x, y, ret;split_by_val(root, v-1, x, y);ret = kth(x, sz[x]);root = merge(x, y);return ret;}inline int suf(int v) {int x, y, ret;split_by_val(root, v, x, y);ret = kth(y, 1);root = merge(x, y);return ret;}
} T;signed main() {int Q;scanf("%d", &Q);while(Q--) {int opt, x;scanf("%d%d", &opt, &x);if(opt == 1) T.ins(x);else if(opt == 2) T.del(x);else if(opt == 3) printf("%d\n", T.get_rank(x));else if(opt == 4) printf("%d\n", T.kth(T.root, x));else if(opt == 5) printf("%d\n", T.pre(x));else if(opt == 6) printf("%d\n", T.suf(x));}
}

三:文艺平衡树

维护一个序列,实现区间翻转
模板题:P3391 【模板】文艺平衡树

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
const int maxn = 5e5 + 5;
int b[maxn];struct Treap {const static int maxn = 5e5 + 5;int root, tot;int sz[maxn], val[maxn], lz[maxn];int rd[maxn], son[maxn][2];Treap() {root = tot = 0;}inline void init() {fill(sz, sz+tot+1, 0);fill(son[0], son[0]+tot+1, 0);fill(son[1], son[1]+tot+1, 0);root = tot = 0;}inline void pushup(int x) {sz[x] = sz[son[x][0]] + sz[son[x][1]] + 1;}inline void pushdown(int x) {swap(son[x][0], son[x][1]);if(son[x][0]) lz[son[x][0]] ^= 1;if(son[x][1]) lz[son[x][1]] ^= 1;lz[x] = 0;}int merge(int x, int y) {if(!x || !y) return x + y;if(rd[x] < rd[y]) {if(lz[x]) pushdown(x);return son[x][1] = merge(son[x][1], y), pushup(x), x;}else {if(lz[y]) pushdown(y);return son[y][0] = merge(x, son[y][0]), pushup(y), y;}}void split_by_sz(int now, int k, int &x, int &y) {if(!now) return x = y = 0, void();if(lz[now]) pushdown(now);if(sz[son[now][0]] >= k) y = now, split_by_sz(son[now][0], k, x, son[now][0]);else x = now, split_by_sz(son[now][1], k-sz[son[now][0]]-1, son[now][1], y);pushup(now);}void insert(int pos, int v) {int u = ++tot, x, y; val[u] = v, sz[u] = 1, rd[u] = rnd();split_by_sz(root, pos-1, x, y);root = merge(merge(x, u), y);}int dfs(int *a, int l, int r) {if(l > r) return 0;int u = ++tot, mid = l + r >> 1;val[u] = a[mid], sz[u] = r - l + 1, rd[u] = rnd();son[u][0] = dfs(a, l, mid-1); son[u][1] = dfs(a, mid+1, r);pushup(u); return u;}void build(int *a, int l, int r) {root = dfs(a, l, r);}void dfs_seq(int u, int *p) {if(u == 0) return;if(lz[u]) pushdown(u);dfs_seq(son[u][0], p);*(p + sz[son[u][0]] + 1) = val[u];dfs_seq(son[u][1], p+sz[son[u][0]]+1);}void seq(int *p) {dfs_seq(root, p);}inline int kth(int now, int k) {    //  查询排名while(true) {if(k <= sz[son[now][0]]) now = son[now][0];else if(k == sz[son[now][0]] + 1) return val[now];else k -= sz[son[now][0]] + 1, now = son[now][1];}}void reverse(int l, int r) {int L, R, l1, r1;split_by_sz(root, r, L, R);split_by_sz(L, l-1, l1, r1);lz[r1] ^= 1;root = merge(merge(l1, r1), R);}
} T;signed main() {int n, m, l, r;scanf("%d%d", &n, &m);
//  for(int i=1; i<=n; i++) T.insert(i, i);for(int i=1; i<=n; i++) b[i] = i;T.build(b, 1, n);while(m--) {scanf("%d%d", &l, &r);T.reverse(l, r);}T.seq(b);for(int i=1; i<=n; i++) printf("%d%c", b[i], " \n"[i==n]);
}

Treap + FHQ Treap相关推荐

  1. FHQ TREAP 学习总结

    F H Q T R E A P FHQ \ TREAP FHQ TREAP P r e p a r e K n o w l e d g e Prepare \ Knowledge Prepare Kn ...

  2. FHQ Treap学习记录(详解)

    前言:嘻嘻,本蒟蒻的第一篇文章!由于本蒟蒻第一次写博客,本文章质量可能不是很好QAQ 前置芝士(了解即可啦~):C++.BST 二叉搜索树.堆.二叉堆 如果您不想听蒟蒻胡扯 Treap,可以直接根据目 ...

  3. P2596 [ZJOI2006]书架(fhq treap)

    P2596 [ZJOI2006]书架 我们用fhq treap来完成这一题 对于一个新插入的节点我们取权值为其索引值,其所记录的valuevaluevalue是其当前索引所在位置. 操作一:把索引为v ...

  4. 可持久化平衡树(FHQ Treap)

    两个最基本的操作 merge合并 split分割 merge 把两棵treap合并成一棵treap,要满足T1最大值要比T2最小值小,比较将随机数值key值更大的作为合并后的根 假设T1作为根节点作为 ...

  5. FHQ Treap 详解

    0. 简单介绍 FHQ Treap,以下简写为fhq,是一种treap(树堆)的变体,功能比treap强大,代码比splay好写,易于理解,常数稍大. fhq不需要通过一般平衡树的左右旋转来保持平衡, ...

  6. FHQ Treap 总结

    [前言(一堆废话)] 目前 OI 竞赛中两大主流平衡树之一就是 FHQ Treap(另一个是 Splay). 普通 BST 的中序遍历中,val 值构成一个单调递增的序列. Treap 在 BST 的 ...

  7. 平衡树学习笔记之 fhq Treap

    平衡树学习笔记 1:fhq Treap(非旋 Treap) 正文开始前首先 %%% fhq 大佬. 众所周知,平衡树是一种 非常猥琐 码量堪忧的数据结构. 他的祖先是一种叫做二叉搜索树 ( B S T ...

  8. 【模板】FHQ Treap

    FHQ Treap 无旋Treap 维护的信息 c h [ i ] [ 0 / 1 ] ch[i][0/1] ch[i][0/1] v a l [ i ] val[i] val[i] f i x [ ...

  9. FHQ Treap【基于P3369的讲解】【随机数、各数组、函数运用】

    该模板题的题目链接 很多人看到了FHQ Treap都不知道它是干什么用的,今天也是刚学的FHQ Treap,学了一整天了,终于过掉了洛谷的P3369了,也算是对这个算法有了些自己的了解,还是错的太多次 ...

最新文章

  1. python3编译exe_编译 – 如何将我的Python 3应用程序编译到.exe?
  2. 外部类的静态成员不允许直接使用非静态内部类
  3. NumberUtils用法
  4. 与aspect长得像的单词_硕士研究生英语81分总结:考研单词这么背才对,方法其实很容易...
  5. git如何强制用远程分支更新本地
  6. php 面向对象 特性,PHP面向对象三大特点学习
  7. C语言入门I love China,C语言从入门到精通
  8. linux下LAMP环境的搭配
  9. python监控错误语句_Sentry错误日志监控使用方法解析
  10. Tomcat 服务详解
  11. JDK 11JAVA11下载分享
  12. Sentaurus TCAD Inspect
  13. HKC PG27P5U评测怎么样
  14. 华为云下docker安装svn
  15. XRecycleView (Scrapped or attached views may not be recycled)
  16. Excel VBA小程序03-快速提取单元格中的数字和非数字
  17. Java java.sql.SQLSyntaxErrorException:Duplicate column name ‘xxx‘问题解决
  18. IGBT静态参数测试系统可测项目有哪些?
  19. 服务器备份应该怎么做
  20. 面试笔试题中的LRU算法及其缺页次数替换

热门文章

  1. 零时科技 || DPC攻击事件分析
  2. 你知道哪些出身最奇特的程序员?
  3. 哈理工OJ 1986 大悲咒(简单递推)
  4. oracle ora-03114
  5. win32中SetCapture 和 ReleaseCapture的使用
  6. tring_vector容器test
  7. Android 监听wifi总结
  8. 微信小程序canvas实现签名功能
  9. Accuracy and precision 意义
  10. 火车头采集细节(二)