无旋Treap的可持久化
解析
其实 F H Q T r e a p FHQ Treap FHQTreap的可持久化非常好理解,只需要的每次操作的 r t rt rt用数组记录下来,然后操作时,节点新建即可
模板题 P3835
注意操作细节
注意数组大小
注意
r
a
n
d
(
)
rand()
rand()的值域
代码
#include<bits/stdc++.h>
#define int long long
#define M 30000009
using namespace std;
const int mod=998244353;
int read(){
int f=1,re=0;
char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-'){f=-1,ch=getchar();}
for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';
return re*f;
}
int val[M],pos[M],siz[M],cnt,root[M],n,son[M][2];
void pushup(int k){siz[k]=siz[son[k][0]]+siz[son[k][1]]+1;}
void copy(int &x,int y){//新建节点
x=++cnt;
son[x][1]=son[y][1],son[x][0]=son[y][0];
siz[x]=siz[y],val[x]=val[y],pos[x]=pos[y];
}
int build(int x){
val[++cnt]=x,siz[cnt]=1,pos[cnt]=rand();
return cnt;
}
void split(int rt,int &a,int &b,int v){
if(!rt){a=b=0;return;}
if(val[rt]<=v) copy(a,rt),split(son[a][1],son[a][1],b,v),pushup(a);
else copy(b,rt),split(son[b][0],a,son[b][0],v),pushup(b);
}
int merge(int a,int b){
int rt;
if(!a||!b) return a+b;
if(pos[a]<pos[b]) copy(rt,a),son[rt][1]=merge(son[rt][1],b);
else copy(rt,b),son[rt][0]=merge(a,son[rt][0]);
pushup(rt);return rt;
}
int kth(int rt,int v){
if(siz[son[rt][0]]>=v) return kth(son[rt][0],v);
if(siz[son[rt][0]]+1==v) return rt;
return kth(son[rt][1],v-siz[son[rt][0]]-1);
}
signed main(){
//srand(time(0));
n=read();
for(int i=1;i<=n;i++){
int t=read(),opt=read(),x=read(),y=0,z=0,w=0;
root[i]=root[t];
if(opt==1) split(root[i],y,z,x),root[i]=merge(merge(y,build(x)),z);
if(opt==2) split(root[i],y,z,x),split(y,y,w,x-1),w=merge(son[w][0],son[w][1]),root[i]=merge(merge(y,w),z);
if(opt==3) split(root[i],y,z,x-1),printf("%lld\n",siz[y]+1),root[i]=merge(y,z);
if(opt==4) printf("%lld\n",val[kth(root[i],x)]);
if(opt==5){
split(root[i],y,z,x-1);
if(y) printf("%lld\n",val[kth(y,siz[y])]),root[i]=merge(y,z);
else printf("-2147483647"),root[i]=merge(y,z);
}
if(opt==6){
split(root[i],y,z,x);
if(z) printf("%lld\n",val[kth(z,1)]),root[i]=merge(y,z);
else printf("2147483647"),root[i]=merge(y,z);
}
}return 0;
}