Treap + 无旋转Treap 学习笔记
普通的Treap模板
今天自己实现成功
/*
* @Author: chenkexing
* @Date: 2019-08-02 20:30:39
* @Last Modified by: chenkexing
* @Last Modified time: 2019-08-02 22:33:17
*/
// #pragma GCC optimize(2)
// #pragma GCC optimize(3)
// #pragma GCC optimize(4)
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert>
// #include<bits/extc++.h>
// using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = ; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /**********showtime************/ struct Node{
Node * ch[];
int r;
int v;
int s;
int cnt;
Node(int val = ){
ch[] = ch[] = NULL;
v = val;
r = rand();
s = ;
cnt = ;
}
int cmp(int x) const{
if(x == v) return -;
return x < v ? : ;
}
void maintain(){
s = cnt;
if(ch[] != NULL) s+=ch[]->s;
if(ch[] != NULL) s+=ch[]->s;
}
}*rt;
void rotate(Node* &o, int d) {
Node* k = o->ch[d^];
o ->ch[d ^ ] = k -> ch[d];
k -> ch[d] = o;
o->maintain();
k->maintain();
o = k;
}
void insert(Node* &o, int x) {
if(o == NULL) {o = new Node(x);}
else if(o->v == x) {o->cnt++;}
else {
int d = o->cmp(x);
insert(o->ch[d], x);
if(o->ch[d] -> r > o->r) rotate(o, d^);
}
o->maintain();
}
void remove(Node* &o, int x) {
int d = o->cmp(x);
if(d == -) {
if(o->cnt > ) o->cnt --;
else if(o->ch[] == NULL) o = o->ch[];
else if(o->ch[] == NULL) o = o->ch[];
else {
int d2 = (o->ch[] -> r > o->ch[] -> r ? : );
rotate(o, d2); remove(o->ch[d2], x);
}
}
else
remove(o->ch[d], x);
if(o != NULL) o->maintain();
}
int find(Node* o, int x) {
while(o != NULL) {
int d = o->cmp(x);
if(d == -) return o->cnt;
else o = o->ch[d];
}
return ;
}
//返回第k小的数,不存在返回-inf
int kth(Node* o, int k){
if(o == NULL || k <= || k > o->s) return -inf;
int s = (o->ch[] == NULL ? : o->ch[]->s);
if(s + <= k && s + o->cnt >= k) return o->v;
else if(s >= k) return kth(o->ch[], k);
else return kth(o->ch[], k - s - o->cnt);
}
//返回比x值小的个数
int rannk(Node* o, int x) {
if(o == NULL) return ;
int s = (o->ch[] == NULL ? : o->ch[]->s);
if(o->v == x) return rannk(o->ch[], x);
else if(o->v > x)return rannk(o->ch[], x);
else return s + o->cnt + rannk(o->ch[], x);
} //合并两个Treap
void mergeto(Node* &src, Node* &dest) {
if(src->ch[] != NULL) mergeto(src->ch[], dest);
if(src->ch[] != NULL) mergeto(src->ch[], dest);
insert(dest, src->v);
delete src;
src = NULL;
} //清空树
void removetree(Node* &x) {
if(x->ch[] != NULL) removetree(x->ch[]);
if(x->ch[] != NULL) removetree(x->ch[]);
delete x;
x = NULL;
}
int main(){
srand(time());
int m; scanf("%d", &m);
while(m --) {
int op,x;
scanf("%d%d", &op, &x);
if(op == ) insert(rt, x);
else if(op == ) remove(rt, x);
else if(op == ) printf("%d\n", rannk(rt, x) + );
else if(op == ) printf("%d\n", kth(rt, x));
else if(op == ) {
int k = rannk(rt, x);
printf("%d\n", kth(rt, k));
}
else {
int k = rannk(rt, x);
k += find(rt, x);
printf("%d\n", kth(rt, k+));
}
}
return ;
}
参考和学习:https://www.cnblogs.com/BCOI/p/9072444.html
对了,参考的blog中删点他应该写错了。
这个是按照val 进行切分的treap
写了模板普通平衡树
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000") //c++
// #pragma GCC diagnostic error "-std=c++11"
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3) #define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull; typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime----------------------*/
const int maxn = ;
int tot = ,root,r1,r2,r3;
struct node{
int sz,val,rd,cnt;
int ch[];
}tr[maxn];
int newNode(int v){
tot++;
tr[tot].sz = ; tr[tot].val = v;tr[tot].rd = rand();
tr[tot].cnt = ;
return tot;
}
void update(int x){
tr[x].sz = tr[tr[x].ch[]].sz + tr[tr[x].ch[]].sz + tr[x].cnt;
} void split(int x,int val, int &a, int &b){
if(!x) {a = b = ;return;}
if(tr[x].val <= val){
a = x; split(tr[x].ch[], val, tr[x].ch[], b);
}
else {
b = x; split(tr[x].ch[], val, a, tr[x].ch[]);
}
update(x);
}
int merge(int x,int y){
if(x == || y == )return x+y;
if(tr[x].rd <= tr[y].rd){
tr[x].ch[] = merge(tr[x].ch[], y);
update(x); return x;
}
else {
tr[y].ch[] = merge(x, tr[y].ch[]);
update(y); return y;
}
} void insert(int val){
split(root, val, r1,r2);
root = merge(r1, merge(newNode(val), r2));
} void delet(int val){
r1 = r2 = r3 = ;split(root,val,r1,r3);
split(r1,val-,r1,r2);
r2 = merge(tr[r2].ch[], tr[r2].ch[]);
root = merge(merge(r1,r2), r3);
} int Rank(int val){
split(root,val-,r1,r2);
int res = tr[r1].sz + ;
merge(r1,r2);
return res;
} int kth(int rt,int k){
int x = rt;
while(true){
if(x == )return -;
if(k <= tr[tr[x].ch[]].sz){
x = tr[x].ch[];
}
else if(k > tr[tr[x].ch[]].sz + tr[x].cnt){
k = k - tr[tr[x].ch[]].sz - tr[x].cnt;
x = tr[x].ch[];
}
else return tr[x].val;
}
} int pre(int val){
r1 = r2 = ;
split(root, val-,r1,r2);
int res = kth(r1, tr[r1].sz);
merge(r1,r2);
return res;
}
int nxt(int val){
r1 = r2 = ;
split(root,val,r1,r2);
int res = kth(r2,);
merge(r1,r2);
return res;
}
int main(){
srand(time());
int t; scanf("%d", &t);
while(t--){
int op,x;
scanf("%d%d", &op, &x);
if(op == ) insert(x);
else if(op == )delet(x);
else if(op == )printf("%d\n", Rank(x));
else if(op == )printf("%d\n", kth(root,x));
else if(op == )printf("%d\n", pre(x));
else if(op == )printf("%d\n", nxt(x));
}
}
Treap
换了个新的FHQ_TREE
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include <bits/stdc++.h> using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = ; /**********showtime************/ struct fhq_treap {
static const int N = 1e5 + ;
struct Node {
int val, key, lc, rc, sz, mx;
}tree[N];
int rt, tot;
inline void init() {
rt = tot = ;
tree[rt].sz = tree[rt].val = tree[rt].lc = tree[rt].rc = ;
srand(time());
}
inline void update(int rt) {
tree[rt].sz = tree[tree[rt].lc].sz + + tree[tree[rt].rc].sz;
tree[rt].mx = max(tree[tree[rt].lc].mx,max(tree[rt].val,tree[tree[rt].rc].mx));
} void split_val(int rt, int &a, int &b, int val) {
if(rt == ) {a = b = ; return ;}
if(max(tree[rt].val , tree[tree[rt].lc].mx) <= val) {
a = rt;
split_val(tree[rt].rc, tree[a].rc, b, val);
}
else {
b = rt;
split_val(tree[rt].lc, a, tree[b].lc, val);
}
update(rt);
}
void split_sz(int rt, int &a, int &b, int sz) {
if(rt == ) {a = b = ; return ;}
if(tree[tree[rt].lc].sz + > sz) {
b = rt;
split_sz(tree[rt].lc, a, tree[b].lc, sz);
}
else {
a = rt;
split_sz(tree[rt].rc, tree[a].rc, b, sz - - tree[tree[rt].lc].sz);
}
update(rt);
} void merge(int &rt, int a, int b) {
if(a== || b==) {
rt = a+b;
return ;
}
if(tree[a].key < tree[b].key) {
rt = a;
merge(tree[rt].rc, tree[a].rc, b);
}
else {
rt = b;
merge(tree[rt].lc, a, tree[b].lc);
}
update(rt);
} inline int new_node(int val) {
tree[++tot].sz = ;
tree[tot].val = val;
tree[tot].lc = tree[tot].rc = ;
tree[tot].key = rand();
tree[tot].mx = val;
return tot;
} void ins(int &rt, int val) {
int x = , y = , node = new_node(val);
merge(rt, rt, node);
}
void delete_node(int &rt, int val) {
int x = , y = , z = ;
split_val(rt, x, y, val);
split_val(x, x, z, val-);
merge(z, tree[z].lc, tree[z].rc);
merge(x, x, z);
merge(rt, x, y);
}
inline int get_kth(int rt, int k) {
while(tree[tree[rt].lc].sz+ != k) {
if(tree[tree[rt].lc].sz >= k) rt = tree[rt].lc;
else k -= tree[tree[rt].lc].sz+, rt = tree[rt].rc;
}
return tree[rt].val;
}
int get_rnk(int &rt, int val) {
int x = , y = ;
split_val(rt, x, y, val-);
int tmp = tree[x].sz+;
merge(rt, x, y);
return tmp;
}
int get_pre(int &rt, int val) {
int x = , y = ;
split_val(rt, x, y, val-);
int tmp = get_kth(x, tree[x].sz);
merge(rt, x, y);
return tmp;
}
int get_scc(int &rt, int val) {
int x = , y = ;
split_val(rt, x, y, val);
int tmp = get_kth(y, );
merge(rt, x, y);
return tmp;
}
}t; const int maxn = 1e5+;
int n,m;
int a[maxn];
void display(int x) {
if(t.tree[x].lc) display(t.tree[x].lc);
if(t.tree[x].rc) display(t.tree[x].rc);
}
void solve(int le, int mid ,int ri) {
int x, y, z;
t.split_sz(t.rt, x, z, ri);
t.split_sz(x, x, y, mid); int tmp;
int r = ;
while(x && y) {
int p = t.get_kth(x, );
int q = t.get_kth(y, ); if(p > q) swap(p, q), swap(x, y);
t.split_val(x, tmp, x, q);
t.merge(r,r, tmp);
}
t.merge(r, r, x);
t.merge(r, r, y);
t.merge(r, r, z);
t.rt = r;
}
int main(){
t.init();
scanf("%d%d", &n, &m);
for(int i=; i<=n; i++) {
scanf("%d", &a[i]);
t.ins(t.rt, a[i]);
}
while(m--){
int op; scanf("%d", &op);
if(op == ) {
int x; scanf("%d", &x);
printf("%d\n", t.get_kth(t.rt, x));
}
else {
int le, mid, ri;
scanf("%d%d%d", &le, &mid, &ri);
solve(le, mid, ri);
}
}
return ;
} /*
5 10
3 2 1 5 4
1 1 2 5 */
Treap + 无旋转Treap 学习笔记的更多相关文章
- 无旋转Treap简介
无旋转Treap是一个神奇的数据结构,能够支持插入,删除,查询k大,查询某个数的排名,查询前驱后继,支持各种区间操作和持久化.基于旋转的Treap无法实现区间反转等操作,但是无旋Treap可以轻易地支 ...
- 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)
在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...
- 【数据结构】【平衡树】无旋转treap
最近在研究平衡树,看起来这种东西又丧水又很深,感觉很难搞清楚.在Ditoly学长的建议下,我先学习了正常的treap,个人感觉这应该是平衡树当中比较好懂的而且比较好写的一种. 然而,发现带旋treap ...
- [NOIP]2017列队——旋转treap/非旋转treap
Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m. 为了便 ...
- jquery无new构建学习笔记
当我们想要创建一个对象,我们可能使用new方法去构建一个对象,那按道理jquery也是一个对象,应该也是用new jquery()来构建呀为什么我们创建jquery对象不用new jquery()而是 ...
- CAS(Compare and Swap)无锁算法-学习笔记
非阻塞同步算法与CAS(Compare and Swap)无锁算法 这篇问题对java的CAS讲的非常透彻! 锁的代价 1. 内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的 ...
- 左偏树 / 非旋转treap学习笔记
背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...
- 【算法学习】Fhq-Treap(无旋Treap)
Treap——大名鼎鼎的随机二叉查找树,以优异的性能和简单的实现在OIer们中广泛流传. 这篇blog介绍一种不需要旋转操作来维护的Treap,即无旋Treap,也称Fhq-Treap. 它的巧妙之处 ...
- 普通平衡树Treap(含旋转)学习笔记
浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...
随机推荐
- ArchSummit分享 | 高德地图App架构演化与实践
讲师介绍 郝仁杰,高德地图无线开发专家.在7月13日落幕的2019年ArchSummit峰会上就高德地图近几年的App架构演化和实践进行了分享. 背景概述 高德是国内领先的数字地图内容.导航和位置服务 ...
- 【译】Hello Kubernetes快速交互实验手册
原文:https://kubernetes.io/docs/tutorials 翻译:Edison Zhou 一.基本介绍 此交互实验可以让你不用搭建K8S环境就可以轻松地尝试管理一个简单的容器化应用 ...
- Python3源代码编译安装
Python3源代码编译安装 安装必要工具 yum-utils ,它的功能是管理repository及扩展包的工具 (主要是针对repository) $ sudo yum install yum-u ...
- MTFlexbox自动化埋点探索
1. 背景 跨平台动态化技术是目前移动互联网领域的重点关注方向,它既能节约人力,又能实现业务快速上线的需求.经过十年的发展,美团App已经变成了一个承载众多业务的超级平台,众多的业务方对业务形态的快速 ...
- K8S搭建-1 Master 2 Workers(dashboard+ingress)
本文讲述k8s最新版的搭建(v1.15.2) 分如下几个topic步骤: 各个节点的基本配置 master节点的构建 worker节点的构建 安装dashboard 安装ingress 常见命令 do ...
- Day4 chart基本属性分析
属性设置是基于chart实例的,所以我们必须先获取一个chart画板实例,获取方式: G2.Chart.创建 Chart 的方式如下: new G2.Chart({ container: {strin ...
- mybatis 源码分析(二)mapper 初始化
mybatis 的初始化还是相对比较复杂,但是作者在初始化过程中使用了多种设计模式,包括建造者.动态代理.策略.外观等,使得代码的逻辑仍然非常清晰,这一点非常值得我们学习: 一.mapper 初始化主 ...
- QFramework 使用指南 2020(二):下载与版本介绍
目前 QFramework 有两个可供安装的版本 PackageKit:QFramework 的插件平台,可以下载只感兴趣的插件,除了 Framework 模块还有一些 Shader 案例.项目模板. ...
- 循环 与 分支语句 和 字符函数库cctype 文件简单处理
循环 for循环 while循环 do while循环 通常,入口条件循环比出口条件循环好,因为循环开始前对条件进行检查 c++11基于范围的for循环 对数组(或容器类,如:vector和a ...
- 对微软的敌视何时休? 从一篇语言评论文章对C#的评价说起
看到一篇公众号文章<2020年什么编程语言最受欢迎,待遇最高?>,其中对C#的描述如下: 点击阅读原文,看到这是一篇翻译文章:https://codinginfinite.com/top- ...