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),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...
 
随机推荐
- Java连接MySQL8.0以上版本数据库方式
			
MySQL 8.0 开始数据库相比常用的 5.X 版本发生了比较大的变化,我们在连接数据库的过程中许多地方也要发生一些变化. 总结一下,想要利用 mysql-connector-java 与 MySQ ...
 - __int64与long long、long的区别
			
首先来看一看int.long.long long的取值范围 int 所占字节数为:4 表示范围为:-2147483648~2147 ...
 - Shiro权限框架与SpringMVC集成
			
1.Shiro整合SpringMVC 我们学习Shiro框架肯定是要应用到Web项目上的,所以我们需要整合Shiro和SpringMVC 整合步骤: 第一步:SpringMVC框架的配置 spring ...
 - ASP.NET Core Identity自定义数据库结构和完全使用Dapper而非EntityFramework Core
			
前言 原本本节内容是不存在的,出于有几个人问到了我:我想使用ASP.NET Core Identity,但是我又不想使用默认生成的数据库表,想自定义一套,我想要使用ASP.NE Core Identi ...
 - MOCTF-WEB-writeup
			
MOCTF-WEB-writeup 好菜,除了简单的几个题,自己会做,难的都是看老大WP完成的,太菜了 啥姿势都不会,就此记录一下,供日后查看及反省.菜鸡的自我修养 0x01 一道水题 题目链接:ht ...
 - 夯实Java基础(十二)——异常处理
			
1.异常处理概述 在Java程序执行过程中, 总是会发生不被期望的事件, 阻止程序按照程序员预期正常运行, 这就是Java程序出现的异常. 异常处理是基于面向对象的一种运行错误处理机制,通过对异常问题 ...
 - Tomcat源码分析 (一)----- 手写一个web服务器
			
作为后端开发人员,在实际的工作中我们会非常高频地使用到web服务器.而tomcat作为web服务器领域中举足轻重的一个web框架,又是不能不学习和了解的. tomcat其实是一个web框架,那么其内部 ...
 - JAVA基础知识(七)存根类
			
存根类是一个类,它实现了一个接口,它的作用是:如果一个接口有很多方法,如果要实现这个接口,就要实现所有的方法.但是一个类从业务来说,可能只需要其中一两个方法.如果直接去实现这个接口,除了实现所需的方法 ...
 - GD32电压不足时烧写程序导致程序运行异常的解决方法
			
一直使用的GD32F450前段时间遇到这样一个问题,当使用J-Link供电给板子烧写程序之后,程序运行缓慢,就像运行在FLASH高速部分之外一样,但是如果使用外部供电烧写,就不会出现这个问题,而且一旦 ...
 - Json串与实体的相互转换 (不依赖于jar包 只需Eclipse环境即可)
			
Json串与实体的相互转换 (不依赖于jar包 只需Eclipse环境即可) 最近学习了javaWeb开发,用的是ssh框架里面自己整合了hibernate 和Struts2 和spring框架,其中 ...