模板汇总——treap
1. 旋转treap。
思想:一颗权值BST + 一颗 随机数 最小堆。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
#define inf 300000030
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
struct Treap{
int L[N], R[N], sz[N], v[N], rnd[N], ct[N], tot, root;
void init(){
tot = root = ;
}
inline int rand(){
static int seed = ;
return seed = (int)seed * 482711LL % ;
}
void Updata(int p){
sz[p] = ct[p] + sz[L[p]] + sz[R[p]];
}
void turnL(int &k){
int t = R[k];
R[k] = L[t];
L[t] = k;
sz[t] = sz[k];
Updata(k);
k = t;
}
void turnR(int &k){
int t = L[k];
L[k] = R[t];
R[t] = k;
sz[t] = sz[k];
Updata(k);
k = t;
}
void Insert(int &p, int x){
if(!p){
p = ++tot;
sz[p] = ct[p] = ;
v[p] = x; rnd[p] = rand();
return ;
}
sz[p]++;
if(v[p] == x) ct[p]++;
else if(x > v[p]){
Insert(R[p], x);
if(rnd[R[p]] < rnd[p]) turnL(p);
}
else {
Insert(L[p], x);
if(rnd[L[p]] < rnd[p]) turnR(p);
}
}
void Delete(int &p, int x){
if(!p) return ;
if(v[p] == x){
if(ct[p] > ) ct[p]--, sz[p]--;
else {
if(L[p] == || R[p] == ) p = L[p] + R[p];
else if(rnd[L[p]] < rnd[R[p]]) turnR(p), Delete(p, x);
else turnL(p), Delete(p, x);
}
}
else if(x > v[p]) sz[p]--, Delete(R[p], x);
else sz[p]--, Delete(L[p], x);
}
int Query_Rank_of_x(int p, int x){
if(!p) return ;
if(v[p] == x) return sz[L[p]]+;
if(v[p] > x) return Query_Rank_of_x(L[p], x);
return ct[p] + sz[L[p]] + Query_Rank_of_x(R[p], x);
}
int Query_kth(int p, int k){
if(!p) return -;
if(sz[L[p]] >= k) return Query_kth(L[p], k);
k -= sz[L[p]];
if(k <= ct[p]) return v[p];
k -= ct[p];
return Query_kth(R[p], k);
}
int FindFront(int p, int x){
if(!p) return -inf;
if(v[p] < x) return max(v[p], FindFront(R[p], x));
return FindFront(L[p], x);
}
int FindNext(int p, int x){
if(!p) return inf;
if(v[p] <= x) return FindNext(R[p], x);
return min(v[p], FindNext(L[p], x));
}
}treap;
int main(){
int T;
int op, x;
scanf("%d", &T);
treap.init();
while(T--){
scanf("%d%d", &op, &x);
if(op == ) treap.Insert(treap.root, x);
else if(op == ) treap.Delete(treap.root, x);
else if(op == ) printf("%d\n", treap.Query_Rank_of_x(treap.root, x));
else if(op == ) printf("%d\n", treap.Query_kth(treap.root, x));
else if(op == ) printf("%d\n", treap.FindFront(treap.root, x));
else if(op == ) printf("%d\n", treap.FindNext(treap.root, x));
}
return ;
}
2.无旋 + 可持久化Treap
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = (int)1e9+;
const int N = 3e6;
const int M = 2e5 + ;
int a[M], top;
int n, m;
struct Treap{
int L[N], R[N], sz[N], v[N], tot, root, prt;
LL sum[N];
inline void init(){
prt = root = tot = ;
}
inline void PushUp(int x){
sz[x] = + sz[L[x]] + sz[R[x]];
sum[x] = v[x] + sum[L[x]] + sum[R[x]];
}
inline int NowNode(int val){
++tot;
L[tot] = R[tot] = ; sz[tot] = ;
v[tot] = sum[tot] = val;
return tot;
}
inline int CopyNode(int pre){
++tot;
L[tot] = L[pre]; R[tot] = R[pre]; sz[tot] = sz[pre];
v[tot] = v[pre]; sum[tot] = sum[pre];
return tot;
}
pll Split(int x, int k){
if(!x) return pll(, );
pll y;
x = CopyNode(x);
if(sz[L[x]] >= k){
y = Split(L[x], k);
L[x] = y.se;
PushUp(x);
y.se = x;
}
else {
y = Split(R[x], k-sz[L[x]]-);
R[x] = y.fi;
PushUp(x);
y.fi = x;
}
return y;
}
int Merge(int x, int y){
if(!x || !y) return x | y;
if(rand() % (sz[x] + sz[y]) <= sz[x]){
x = CopyNode(x);
R[x] = Merge(R[x], y);
PushUp(x);
return x;
}
else {
y = CopyNode(y);
L[y] = Merge(x, L[y]);
PushUp(y);
return y;
}
}
LL Query_kth_sum(int x, int k){
if(!x || !k) return ;
if(sz[L[x]] >= k) return Query_kth_sum(L[x], k);
return Query_kth_sum(R[x], k-sz[L[x]]-) + sum[L[x]] + v[x];
}
LL Querysum(int l, int r){
return Query_kth_sum(root, r) - Query_kth_sum(root, l-);
}
void Updata1(int l, int r, int k){
/// ... l-k ... l .... r .... n
pll p1 = Split(root, r);
pll p2 = Split(p1.fi, l-);
pll p3 = Split(p2.fi, l-k-);
int zzz = p3.se;
while(sz[zzz] < r - l + ) zzz = Merge(zzz, zzz);
pll p4 = Split(zzz, r-l+);
root = Merge(p2.fi, p4.fi);
root = Merge(root, p1.se);
}
void Updata2(int l, int r){
pll p1 = Split(prt, r);
p1 = Split(p1.fi, l-);
pll p2 = Split(root, r);
pll p3 = Split(p2.fi, l-);
root = Merge(p3.fi, p1.se);
root = Merge(root, p2.se);
}
void Build(int & x, int l, int r){
if(l > r) {x = ; return;}
int m = l+r >> ;
x = NowNode(a[m]);
Build(L[x], l, m-);
Build(R[x], m+, r);
PushUp(x);
}
void dfs(int x){
if(!x) return ;
dfs(L[x]);
a[++top] = v[x];
dfs(R[x]);
}
void ReBuild(){
tot = sz[prt];
top = ;
dfs(root);
Build(root, , n);
}
}treap;
int main(){
treap.init();
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
scanf("%d", &a[i]);
treap.Build(treap.root, , n);
treap.prt = treap.root;
int MaxP = 2e6 + 5e5;
int op, l, r, k;
for(int i = ; i <= m; ++i){
scanf("%d", &op);
if(op == ) {
scanf("%d%d", &l, &r);
printf("%lld\n", treap.Querysum(l, r));
}
else if(op == ){
scanf("%d%d%d", &l, &r, &k);
treap.Updata1(l, r, k);
}
else {
scanf("%d%d", &l, &r);
treap.Updata2(l, r);
}
if(treap.tot > MaxP){
treap.ReBuild();
}
}
return ;
}
3.普通treap
19牛客多校4F
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int n, m;
struct Treap{
int L[N], R[N], sz[N], v[N], tot, root, prt, key[N];
int Max[N];
inline void init(){
root = tot = ;
}
inline void PushUp(int x){
sz[x] = + sz[L[x]] + sz[R[x]];
Max[x] = max({v[x], Max[L[x]], Max[R[x]]});
}
void Split(int x, int k, int &l, int &r){
if(!x) {l = r = ; return ;}
if(sz[L[x]] >= k){
r = x;
Split(L[x], k, l, L[x]);
}
else {
l = x;
Split(R[x], k-sz[L[x]]-, R[x], r);
}
if(l) PushUp(l);
if(r) PushUp(r);
}
int Merge(int x, int y){
if(!x || !y) return x | y;
if(key[x] > key[y]){
R[x] = Merge(R[x], y);
PushUp(x);
return x;
}
else {
L[y] = Merge(x, L[y]);
PushUp(y);
return y;
}
}
inline void NowNode(int val){
++tot;
L[tot] = R[tot] = ; sz[tot] = ;
v[tot] = Max[tot] = val;
key[tot] = rand();
root = Merge(root, tot);
}
int Query_kth(int x, int k){
if(sz[L[x]] >= k) return Query_kth(L[x], k);
else k -= sz[L[x]];
if(k == ) return v[x];
k -= ;
return Query_kth(R[x], k);
}
int get_lens(int x, int val){
if(!x) return ;
if(Max[L[x]] > val) return get_lens(L[x], val);
if(v[x] > val) return sz[L[x]];
return sz[L[x]] + + get_lens(R[x], val);
}
void solve(){
int l, m, r;
scanf("%d%d%d", &l, &m, &r);
int t1, t2, t3;
Split(root, r, t1, t2);
root = t1;
Split(root, m, t1, t3);
root = ;
while(t1 && t3){
int A = Query_kth(t1, ), B = Query_kth(t3, );
if(A > B) {
swap(A, B);
swap(t1, t3);
}
int len = get_lens(t1, B), tmp;
Split(t1, len, tmp, t1);
root = Merge(root, tmp);
}
if(t1) root = Merge(root, t1);
if(t3) root = Merge(root, t3);
root = Merge(root, t2);
}
}treap;
int main(){
treap.init();
srand(time());
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i){
int v;
scanf("%d", &v);
treap.NowNode(v);
}
int op;
for(int i = ; i <= m; ++i){
scanf("%d", &op);
if(op == )
treap.solve();
else {
scanf("%d", &op);
printf("%d\n", treap.Query_kth(treap.root, op));
}
}
return ;
}
模板汇总——treap的更多相关文章
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
- 【POJ各种模板汇总】(写在逆风省选前)(不断更新中)
1.POJ1258 水水的prim……不过poj上硬是没过,wikioi上的原题却过了 #include<cstring> #include<algorithm> #inclu ...
- 单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板
一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的 ...
- 算法模板——平衡树Treap
实现功能如下——1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小于x,且最大 ...
- 【模板】Treap
Treap,又称树堆,是一种通过堆性质来维持BST平衡的数据结构.具体体现在对于树上每一个点来说,既有BST维护的值,又有一个堆维护的随机生成的值.维护平衡性的办法是根据堆维护的值的相对大小关系进行左 ...
- 【模板】NOIP模板汇总
图论 数据结构 数学 其他: 洛谷模板:a,b两个字符串,求b串在a串中出现的位置 #include<iostream> #include<cstdio> #include&l ...
- 模板汇总——KMP & EX-KMP
1. kmp 相当于往前求出一段字符信息,使得 这段字符信息和前缀相等. void getnext(){ , j = ; nx[] = -; while(j < m){ || b[j] == b ...
- 模板汇总——AC自动机
AC自动机 模板题 HDU-2222 Keywords Search #include<bits/stdc++.h> using namespace std; #define LL lon ...
- 模板 - 数据结构 - Treap
还有人把Treap叫做树堆的,但是常用名还是叫做Treap的比较多. 不进行任何封装的,带求和操作的,一个节点存放多个元素的最普通的Treap. #include<bits/stdc++.h&g ...
随机推荐
- 虚拟机ip地址从ipv6改为ipv4相关问题
有一次打开虚拟机时,Xshell连接不上虚拟机,就很奇怪,然后查看虚拟机的ip地址,发现显示为ipv6格式,然后总结了两种情况如下: 第一种情况: onboot为no时显示ipv6地址, 改为yes即 ...
- WPF中如何禁用空格键(或其他键)
在选择的控件中添加KeyDown event method private void OnKeyDown(object sender, KeyEventArgs e){ if (e.Key == Ke ...
- pod指定node运行
1.给node打上label kubectl label nodes cn-hongkong.i-j6c5pm0b59y9kaos565o apptype=monitoring 2.查看结果kubec ...
- 史上最全面的SignalR系列教程-1、认识SignalR
SignalR 是什么? SignalR 是一个面向 ASP.NET 开发人员的库,可简化将实时 web 功能添加到应用程序的过程. 实时 web 功能是让服务器代码将内容推送到连接的客户端立即可用, ...
- 深扒JVM,对它进行“开膛破肚”式解析!
1. 打怪升级,你绕不开JVM JVM,对Java程序员进阶而言,是一个绝对绕不开,也不能绕开的话题. 在你打怪升级.进阶蜕变的路上,势必会遇到项目上线中各种OOM.GC等问题,此时JVM的功底就至关 ...
- [Spring cloud 一步步实现广告系统] 15. 使用开源组件监听Binlog 实现增量索引准备
MySQL Binlog简介 什么是binlog? 一个二进制日志,用来记录对数据发生或潜在发生更改的SQL语句,并以而进行的形式保存在磁盘中. binlog 的作用? 最主要有3个用途: 数据复制( ...
- java8(一)Lambda表达式
其实很久前已经学习过了Lambda表达式,但是学习后没有多少使用的机会,久而久之也就忘记(惭愧).最近新的项目用的jdk8所以准备再学习一次,写下文章也是为了记录,方便以后再忘的时候,不用到处找资料( ...
- CSS3: @font-face 介绍与使用
@font-face 是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,你们当中或许有 ...
- canvas 使用图片跨域问题
项目中需要生成海报,使用了前端生成图片的插件,将背景图,详情图,以及部分的文字说明放在一块并且生成一张新的图片,大体看了一下源码是通过canvas来实现的,在本地的时候完全没有问题,提交到服务器之后就 ...
- python random 模块及验证码功能
random模块 import random random.random() random.randint(1,3) # 1-3的整数包括3 import random print(random.ra ...