因为(Treap)只认儿子不认爸爸,所以方便复制,直接可持久化就行了
(code:)
int add(int x)
{
val[++tot]=x;
siz[tot]=1;
key[tot]=rand();
return tot;
}
void pushup(int x)
{
siz[x]=siz[ls[x]]+siz[rs[x]]+1;
}
int cpy(int x)
{
tot++;
val[tot]=val[x];
siz[tot]=siz[x];
key[tot]=key[x];
ls[tot]=ls[x];
rs[tot]=rs[x];
return tot;
}
void merge(int &p,int x,int y)
{
if(!x||!y)
{
p=x+y;
return;
}
if(key[x]<key[y]) p=cpy(x),merge(rs[p],rs[p],y);
else p=cpy(y),merge(ls[p],x,ls[p]);
pushup(p);
}
void split(int p,int k,int &x,int &y)
{
if(!p)
{
x=y=0;
return;
}
if(val[p]<=k)
{
x=cpy(p);
split(rs[x],k,rs[x],y);
pushup(x);
}
else
{
y=cpy(p);
split(ls[y],k,x,ls[y]);
pushup(y);
}
}
int query(int p,int k)
{
if(k==siz[ls[p]]+1) return val[p];
if(k<=siz[ls[p]]) return query(ls[p],k);
else return query(rs[p],k-siz[ls[p]]-1);
}
split(root[i],a,x,y);
merge(x,x,add(a));
merge(root[i],x,y);//插入
split(root[i],a,x,y);
split(x,a-1,x,z);
merge(z,ls[z],rs[z]);
merge(x,x,z);
merge(root[i],x,y);//删除
split(root[i],a-1,x,y);
printf("%d
",siz[x]+1);
merge(root[i],x,y);//查询x的排名
printf("%d
",query(root[i],a));//查询排名为x的数
split(root[i],a-1,x,y);
if(!siz[x]) puts("-2147483647");
printf("%d
",query(x,siz[x]));
merge(root[i],x,y);//前驱
split(root[i],a,x,y);
if(!siz[y]) puts("2147483647");
else printf("%d
",query(y,1));
merge(root[i],x,y);//后继