一、题目
二、解法
其实可持久化的思路很简单,就是你永远不改原版,而是在新建点上修改。
所以在 merge,split \text{merge,split} merge,split的时候用新开的点就行了。
#include <cstdio>
#include <cstdlib>
#include <ctime>
#define inf 2147483647
const int MAXN = 500005;
const int MAXM = 80*MAXN;
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,cnt,now,rt[MAXN];
int ch[MAXM][2],siz[MAXM],val[MAXM],hp[MAXM];
struct node
{
int p[2];
node() {p[0]=p[1]=0;}
}emp;
void copy(int a,int b)
{
ch[b][0]=ch[a][0];ch[b][1]=ch[a][1];
siz[b]=siz[a];val[b]=val[a];hp[b]=hp[a];
}
void up(int x)
{
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
node split(int x,int v)
{
if(!x) return emp;
int d=val[x]<=v,t=++cnt;
copy(x,t);
node y=split(ch[t][d],v);
ch[t][d]=y.p[d^1];
y.p[d^1]=t;
up(t);
return y;
}
node split_(int x,int s)
{
if(!x) return emp;
node y;
int t=++cnt;copy(x,t);
if(siz[ch[t][0]]>=s)
{
y=split_(ch[t][0],s);
ch[t][0]=y.p[1];
y.p[1]=t;
}
else
{
y=split_(ch[t][1],s-siz[ch[t][0]]-1);
ch[t][1]=y.p[0];
y.p[0]=t;
}
up(t);
return y;
}
int merge(int x,int y)
{
if(!x || !y) return x+y;
if(hp[x]<hp[y])
{
int t=++cnt;copy(x,t);
ch[t][1]=merge(ch[t][1],y);
up(t);
return t;
}
int t=++cnt;copy(y,t);
ch[t][0]=merge(x,ch[t][0]);
up(t);
return t;
}
void ins(int v)
{
node x=split(rt[now],v-1);
int t=++cnt;
siz[t]=1;val[t]=v;hp[t]=rand();
rt[now]=merge(x.p[0],merge(t,x.p[1]));
}
void del(int v)
{
node x=split(rt[now],v-1),y=split_(x.p[1],1);
if(val[y.p[0]]!=v)
rt[now]=merge(x.p[0],merge(y.p[0],y.p[1]));
else
rt[now]=merge(x.p[0],y.p[1]);
}
int rank(int v)
{
node x=split(rt[now],v-1);
int ans=siz[x.p[0]]+1;
rt[now]=merge(x.p[0],x.p[1]);
return ans;
}
int ask(int v)
{
node x=split_(rt[now],v-1),y=split_(x.p[1],1);
int ans=val[y.p[0]];
rt[now]=merge(x.p[0],merge(y.p[0],y.p[1]));
return ans;
}
int pre(int v)
{
node x=split(rt[now],v-1),y=split_(x.p[0],siz[x.p[0]]-1);
int ans=val[y.p[1]];
rt[now]=merge(merge(y.p[0],y.p[1]),x.p[1]);
return ans;
}
int suf(int v)
{
node x=split(rt[now],v),y=split_(x.p[1],1);
int ans=val[y.p[0]];
rt[now]=merge(x.p[0],merge(y.p[0],y.p[1]));
return ans;
}
int main()
{
srand(time(0));
n=read();
ins(-inf);ins(inf);
for(int i=1;i<=n;i++)
{
int ver=read(),op=read(),v=read();
rt[i]=rt[ver];
now=i;
if(op==1) ins(v);
if(op==2) del(v);
if(op==3) printf("%d\n",rank(v)-1);
if(op==4) printf("%d\n",ask(v+1));
if(op==5) printf("%d\n",pre(v));
if(op==6) printf("%d\n",suf(v));
}
}