FHQ Treap树
Treap树简介
Treap是一个合成词,Treap=Tree+Heap,顾名思义,它是具有堆性质的树,它的本质还是BST(二叉查找树),但因为引入了随机的权值使其在概率期望上达到了 l o g 2 n log_2{n} log2n的复杂度。
Treap树的维护有旋转法和FHQ两种方式,FHQ是近年来逐渐流行的,其编码更加简单且可以解决区间翻转和区间移动等问题。
FHQ Treap树例题
P3391 【模板】文艺平衡树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct Node {
int ls, rs;
int pri; //权值
int num;//储存值
int size;//子树大小
int lazy;
} t[N];
int cnt = 0,root=0;
void pushdown(int x){
if(t[x].lazy){
swap(t[x].ls,t[x].rs);
t[t[x].ls].lazy^=1;
t[t[x].rs].lazy^=1;
t[x].lazy=0;
}
}
void NewNode(int x) {
++cnt;
t[cnt].ls = t[cnt].rs = t[cnt].lazy = 0;
t[cnt].size = 1;
t[cnt].num = x;
t[cnt].pri = rand();
}
void Update(int x){
t[x].size=t[t[x].ls].size+t[t[x].rs].size+1;
}
int Merge(int L,int R){
if(L==0||R==0)
return L+R;
if(t[L].pri>t[R].pri) {
pushdown(L);
t[L].rs = Merge(t[L].rs, R);
Update(L);
return L;
}
else {
pushdown(R);
t[R].ls = Merge(L, t[R].ls);
Update(R);
return R;
}
}
void inorder(int u){
if(u==0)
return;
pushdown(u);
inorder(t[u].ls);
cout<< t[u].num << " ";
inorder(t[u].rs);
}
void Split(int u,int x,int &L,int &R){
if(u==0){
L=R=0;
return;
}
pushdown(u);
if (t[t[u].ls].size+1<=x){
L=u;
Split(t[u].rs,x-(t[t[u].ls].size+1),t[L].rs,R);
}
else{
R=u;
Split(t[u].ls,x,L,t[R].ls);
}
Update(u);
}
int main() {
srand(time(NULL));
int m, n;
cin >> m >> n;
for(int i=1;i<=n;i++) {
NewNode(i);
root = Merge(root,cnt);
}
int l, r;
int L,R,M;
while (m--) {
cin >> l >> r;
Split(root,r,L,R);
Split(L,l-1,L,M);
t[M].lazy^=1;
root= Merge(Merge(L,M),R);
}
inorder(root);
return 0;
}