平衡树模板
来源:互联网 发布:微博怎么认证淘宝卖家 编辑:程序博客网 时间:2024/06/06 00:50
Splay
仅支持构造、插入、查找、翻转。
#include <cstdio>#include <cstring>#define R register#define Null bint n, m;struct Data { int Key, Sum; bool rev; Data *Pre, *Son[2]; } b[100010], *root = b; int tot;struct Splay_Tree{ void Pushup(R Data *Now){ Now->Sum = Now->Son[0]->Sum + Now->Son[1]->Sum + 1; } void Swap(R Data *&A, R Data *&B){ R Data *t = A; A = B; B = t; } void Pushdown(R Data *Now) { if(Now->rev) { Swap(Now->Son[0], Now->Son[1]); Now->Son[0]->rev ^= 1, Now->Son[1]->rev ^= 1; Now->rev = 0; } } void Rotate(R Data *Now) { R bool d = (Now->Pre->Son[1] == Now); R Data *f = Now->Pre; f->Son[d] = Now->Son[!d]; Now->Son[!d]->Pre = f; Now->Pre = f->Pre; f->Pre->Son[f->Pre->Son[1] == f] = Now; f->Pre = Now; Now->Son[!d] = f; Pushup(f); } void Preview(R Data *Now, R Data *Fa) { if(Now->Pre != Fa) Preview(Now->Pre, Fa); Pushdown(Now); } void Splay(R Data *Now, R Data *Fa = Null) { Preview(Now, Fa); while(Fa != Now->Pre) { if(Now->Pre->Pre != Fa) Rotate((Now->Pre->Pre->Son[0] == Now->Pre) ^ (Now->Pre->Son[0] == Now) ? Now : Now->Pre); Rotate(Now); } Pushup(Now); Fa == Null ? root = Now : 0; } void Insert(int x) { if(root == Null) b[++tot] = (Data) {x, 1, 0, Null, Null, Null}, root = b + tot; else { R Data *Now = root; while(Now != Null) { if(Now->Son[Now->Key < x] == Null) { b[++tot] = (Data) {x, 1, 0, Now, Null, Null}; Now->Son[Now->Key < x] = b + tot; break; } else Now = Now->Son[Now->Key < x]; } Splay(Now); } } void Print(R Data *Now) { Pushdown(Now); if(Now->Son[0] != Null) Print(Now->Son[0]); printf("%d ", Now->Key); if(Now->Son[1] != Null) Print(Now->Son[1]); } Data* Select(R int K, R Data *Now = root) { Pushdown(Now); if(Now->Son[0]->Sum >= K) return Select(K, Now->Son[0]); else if(Now->Son[0]->Sum == K - 1) return Now; else return Select(K - Now->Son[0]->Sum - 1, Now->Son[1]); } void Reverse(R int l, R int r) { if(l - 1 == 0 && r + 1 > n) root->rev ^= 1; else if(l - 1 == 0) Splay(Select(r + 1)), root->Son[0]->rev ^= 1; else if(r + 1 > n) Splay(Select(l - 1)), root->Son[1]->rev ^= 1; else { R Data *u = Select(l - 1), *v = Select(r + 1); Splay(u); Splay(v, u); root->Son[1]->Son[0]->rev ^= 1; } } Data* Build(R int begin, R int end) { if(begin > end) return Null; R int mid = begin + end >> 1; b[++tot] = (Data) {mid, 1, 0, Null, Null, Null}; R Data *Now = b + tot; (Now->Son[1] = Build(mid + 1, end))->Pre = Now; (Now->Son[0] = Build(begin, mid - 1))->Pre = Now; Now->Sum += Now->Son[0]->Sum + Now->Son[1]->Sum; return Now; }} a;int main(){ b[0] = (Data) {0, 0, 0, Null, Null, Null}; scanf("%d %d", &n, &m); root = a.Build(1, n); for(R int i = 1; i <= m; i++) { R int l, r; scanf("%d %d", &l, &r); a.Reverse(l, r); } a.Print(root); return 0;}
Treap
非旋转,仅支持插入、删除、查找、翻转。
#include <cstdio>#include <cstring>#include <cstdlib>#define rand() (rand() ^ rand())#define R register#define Null bint rnd(){ unsigned x = rand(); x = x << 15 ^ rand(); x = x << 2 ^ rand(); return x >> 1;}int n, m;struct Data { int Key, Val, Sum; bool rev; Data *lson, *rson;} b[100010], *root = Null; int tot;struct Treap{ void Swap(R Data *&A, R Data *&B) { R Data *t = A; A = B; B = t; } void Pushdown(R Data *Now) { if(Now->rev) { Swap(Now->lson, Now->rson); Now->lson->rev ^= 1; Now->rson->rev ^= 1; Now->rev = 0; } } void Pushup(R Data *Now){ Now->Sum = Now->lson->Sum + Now->rson->Sum + 1; } Data* Merge(R Data *A, R Data *B) { if(A == Null || B == Null) return A == Null ? B : A; Pushdown(A); Pushdown(B); if(A->Val > B->Val) A->rson = Merge(A->rson, B); else B->lson = Merge(A, B->lson); Pushup(A->Val > B->Val ? A : B); return A->Val > B->Val ? A : B; } void *Split(R Data *Now, R int K, R Data *&A, R Data *&B) { if(Now == Null) A = B = Null; else { Pushdown(Now); if(Now->lson->Sum >= K) { B = Now; Split(Now->lson, K, A, Now->lson); } else { A = Now; Split(Now->rson, K - Now->lson->Sum - 1, Now->rson, B); } Pushup(Now); } } void Insert(int x) { b[++tot] = (Data) {x, rnd(), 1, 0, Null, Null}; root = Merge(root, b + tot); } void Reverse(int l, R int r) { R Data *A, *B, *C; if(l - 1 == 0 && r + 1 > n) root->rev ^= 1; else if(l - 1 == 0) { Split(root, r, A, B); A->rev ^= 1; root = Merge(A, B); } else if(r + 1 > n) { Split(root, l - 1, A, B); B->rev ^= 1; root = Merge(A, B); } else { Split(root, l - 1, A, B); Split(B, r - l + 1, B, C); B->rev ^= 1; root = Merge(Merge(A, B), C); } } void Print(R Data *Now) { Pushdown(Now); if(Now->lson != Null) Print(Now->lson); printf("%d ", Now->Key); if(Now->rson != Null) Print(Now->rson); } Data* Build(R int begin, R int end, R int Id) { if(begin > end) return Null; R int mid = begin + end >> 1; b[++tot] = (Data) {mid, Id, 1, 0, Null, Null}; R Data *Now = b + tot; Now->rson = Build(mid + 1, end, Id - 1); Now->lson = Build(begin, mid - 1, Id - 1); Now->Sum += Now->lson->Sum + Now->rson->Sum; return Now; }} a;int main(){ b[0] = (Data){0, 0, 0, 0, Null, Null}; scanf("%d %d", &n, &m); root = a.Build(1, n, n); for(R int i = 1; i <= m; i++) { R int l, r; scanf("%d %d", &l, &r); a.Reverse(l, r); } a.Print(root); return 0;}
阅读全文
0 0
- (模板)平衡二叉树
- 平衡树模板
- 平衡树SBT模板
- 平衡二叉树模板
- 平衡二叉树模板
- [平衡树模板]Treap
- 平衡树模板
- [模板]平衡树treap
- pb_ds平衡树-模板
- SBT 平衡二叉树模板
- C++ AVL平衡树 模板
- 平衡二叉树SBT模板
- 平衡二叉树C++模板
- 平衡树模板三题
- 【模板】普通平衡树 Treap
- 【模板】二逼平衡树
- 平衡树模板&&bzoj 3223&&Tyvj 1729 文艺平衡树
- 【BZOJ】3224 Tyvj 1728 普通平衡树 平衡树模板
- 软件工程中的文档轨迹化
- Java.lang.OutOfMemoryError: PermGen space及其解决方法
- 互联网时代下的大数据
- Codeforces Round #400 (Div. 1 + Div. 2, combined) 776C Molly's Chemicals
- web安全概略
- 平衡树模板
- C语言实验——计算1到n的和(循环结构)
- 分布式锁与实现(一)——基于Redis实现
- Python学习笔记1-List,tuple
- 关于IO与NIO的资料整理
- Spring Boot教程
- 微电网研究相关_实际背景搜集20171118
- 基于Python+selenium的自动化测试基础
- 第一篇博客