可持久化平衡树

因为\(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\n",siz[x]+1);
merge(root[i],x,y);//查询x的排名
		
printf("%d\n",query(root[i],a));//查询排名为x的数

split(root[i],a-1,x,y);
if(!siz[x]) puts("-2147483647");
printf("%d\n",query(x,siz[x]));
merge(root[i],x,y);//前驱

split(root[i],a,x,y);
if(!siz[y]) puts("2147483647");
else printf("%d\n",query(y,1));
merge(root[i],x,y);//后继
posted @ 2020-01-22 20:35  lhm_liu  阅读(313)  评论(0编辑  收藏  举报