可持久化 FHQ Treap
建议优先阅读可持久化线段树。
可持久化 FHQ Treap
同可持久化线段树,可持久化平衡树的原理也是充分利用过去版本信息。
在 split 操作中,不断复制节点即可构造新版本。
是的,结束了。
事实上,诸多可持久化数据结构都是如此原理。
例题 AC 代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
#include<random>
using namespace std;
mt19937 Rand(time(0));
constexpr const int N=5e5;
struct FHQTreap{
int root[N+1];
int size;
struct node{
int value,size,rand;
int lChild,rChild;
}t[N*100+1];
FHQTreap(){
size=0;
}
int clone(int p){
t[++size]=t[p];
return size;
}
int create(int x){
t[++size]={x,1,Rand(),0,0};
return size;
}
void up(int p){
t[p].size=t[t[p].lChild].size + 1 + t[t[p].rChild].size;
}
void split(int p,int x,int &l,int &r){
if(!p){
l=r=0;
return;
}
p=clone(p);
if(t[p].value<=x){
l=p;
split(t[p].rChild,x,t[p].rChild,r);
}else{
r=p;
split(t[p].lChild,x,l,t[r].lChild);
}
up(p);
}
int merge(int l,int r){
if(!l||!r){
return l|r;
}
if(t[l].rand<t[r].rand){
t[l].rChild=merge(t[l].rChild,r);
up(l);
return l;
}else{
t[r].lChild=merge(l,t[r].lChild);
up(r);
return r;
}
}
void insert(int v,int i,int x){
int l,r,p;
split(root[v],x,l,r);
root[i]=merge(merge(l,create(x)),r);
}
void erase(int v,int i,int x){
int l,r,p;
split(root[v],x,l,r);
split(l,x-1,l,p);
p=merge(t[p].lChild,t[p].rChild);
root[i]=merge(merge(l,p),r);
}
int rank(int v,int i,int x){
int l,r;
split(root[v],x-1,l,r);
int ans=t[l].size+1;
root[i]=merge(l,r);
return ans;
}
int kth(int v,int i,int k,int p=-1){
if(p==-1){
p=root[v];
}
while(true){
if(t[t[p].lChild].size+1==k){
break;
}else if(t[t[p].lChild].size+1<k){
k-=t[t[p].lChild].size+1;
p=t[p].rChild;
}else{
p=t[p].lChild;
}
}
root[i]=root[v];
return t[p].value;
}
int prev(int v,int i,int x){
int l,r;
split(root[v],x-1,l,r);
int ans=kth(0,0,t[l].size,l);
root[i]=merge(l,r);
return ans;
}
int next(int v,int i,int x){
int l,r;
split(root[v],x,l,r);
int ans=kth(0,0,1,r);
root[i]=merge(l,r);
return ans;
}
void print(int v,int p=-1){
if(p==-1){
p=root[v];
}
if(!p){
return;
}
print(v,t[p].lChild);
cerr<<t[p].value<<' ';
print(v,t[p].rChild);
}
}t;
int main(){
/*freopen("test.in","r",stdin);
freopen("test.out","w",stdout);*/
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++){
int v,opt,x;
cin>>v>>opt>>x;
switch(opt){
case 1:
t.insert(v,i,x);
break;
case 2:
t.erase(v,i,x);
break;
case 3:
cout<<t.rank(v,i,x)<<'\n';
break;
case 4:
cout<<t.kth(v,i,x)<<'\n';
break;
case 5:
cout<<t.prev(v,i,x)<<'\n';
break;
case 6:
cout<<t.next(v,i,x)<<'\n';
break;
}
}
cout.flush();
/*fclose(stdin);
fclose(stdout);*/
return 0;
}
/*
9
0 1 9
1 1 3
1 1 10
2 4 2
3 3 9
2 4 2
3 3 9
2 4 2
3 3 9
*/

浙公网安备 33010602011771号