标签:维护 str upd algorithm 平衡 data spl online pac
自己开的可持久化的坑,自己含着泪也要补完≡(▔﹏▔)≡
之前刚刚学过fhq_treap 这个数据结构的强大之处:一在于好写好调,码量友好;二便在于便于可持久化
因为普通treap利用旋转来保持时间复杂度,左旋旋,右旋旋,很难维护父子关系,也很难像主席树那样大规模的利用历史数据。但是非旋treap就有个“形态固定”的优美性质,适合可持久化
直接讲做法:
直接在split做出更改。每一次将一棵树份成两半的时候都新建节点即可。over。就这么点。
new split:
void split(int now,int k,int &x,int &y){
if(!now) x=y=0;
else{
if(val[now]<=k){
x=++tot;
copy_node(now,x);
split(ch[x][1],k,ch[x][1],y);
updata(x);
}
else {
y=++tot;
copy_node(now,y);
split(ch[y][0],k,x,ch[y][0]);
updata(y);
}
updata(now);
}
}
完整代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define FT fhq_treap::
namespace fhq_treap{
const int MAX=5e7+5;
int tot,x,y,z;
int root[MAX],ch[MAX][2],val[MAX],rad[MAX],size[MAX];
void updata(int k){
size[k]=1+size[ch[k][0]]+size[ch[k][1]];
}
int newnode(int k){
tot++;
val[tot]=k;
rad[tot]=rand();
size[tot]=1;
return tot;
}
void copy_node(int a,int b){
val[b]=val[a];
size[b]=size[a];
rad[b]=rad[a];
ch[b][0]=ch[a][0];
ch[b][1]=ch[a][1];
}
void copy(int a,int b){
root[b]=++tot;
copy_node(root[a],root[b]);
}
void split(int now,int k,int &x,int &y){
if(!now) x=y=0;
else{
if(val[now]<=k){
x=++tot;
copy_node(now,x);
split(ch[x][1],k,ch[x][1],y);
updata(x);
}
else {
y=++tot;
copy_node(now,y);
split(ch[y][0],k,x,ch[y][0]);
updata(y);
}
updata(now);
}
}
int merge(int a,int b){
if(!a||!b) return a|b;
else{
if(rad[a]<rad[b]){
ch[a][1]=merge(ch[a][1],b);
updata(a);
return a;
}
else{
ch[b][0]=merge(a,ch[b][0]);
updata(b);
return b;
}
}
}
void insert(int ver,int k){
split(root[ver],k,x,z);
x=merge(x,newnode(k)); root[ver]=merge(x,z);
}
void delate(int ver,int k){
split(root[ver],k-1,x,y);
split(y,k,y,z);
y=merge(ch[y][0],ch[y][1]);
x=merge(x,y); root[ver]=merge(x,z);
}
int rak(int ver,int k){
split(root[ver],k-1,x,y);
int ans=size[x]+1;
root[ver]=merge(x,y);
return ans;
}
int kth(int p,int k){
int now=p;
while(now){
int t=size[ch[now][0]]+1;
if(t==k) return now;
else if(k<=t) now=ch[now][0];
else {k-=t; now=ch[now][1];}
}
}
int pre(int ver,int k){
split(root[ver],k-1,x,y);
int ans=val[kth(x,size[x])];
root[ver]=merge(x,y);
return ans;
}
int suf(int ver,int k){
split(root[ver],k,x,y);
int ans=val[kth(y,1)];
root[ver]=merge(x,y);
return ans;
}
bool exist(int ver,int k){
split(root[ver],k-1,x,y);
split(y,k,y,z);
bool ans=size[y];
x=merge(x,y); root[ver]=merge(x,z);
return ans;
}
}
int n;
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
FT insert(0,-2147483647);
FT insert(0,2147483647);
scanf("%d",&n);
for(int i=1;i<=n;++i){
int v,opt,x; scanf("%d%d%d",&v,&opt,&x);
FT copy(v,i);
switch(opt){
case 1:
FT insert(i,x);
break;
case 2:
FT delate(i,x);
break;
case 3:
printf("%d\n",FT rak(i,x)-1);
break;
case 4:
printf("%d\n",FT val[FT kth(FT root[i],x+1)]);
break;
case 5:
printf("%d\n",FT pre(i,x));
break;
case 6:
printf("%d\n",FT suf(i,x));
break;
}
}
return 0;
}
标签:维护 str upd algorithm 平衡 data spl online pac
原文地址:https://www.cnblogs.com/ticmis/p/13210593.html