• 可持久化平衡树


    因为(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);//后继
    
  • 相关阅读:
    再见 2020, 愿“山河无恙,人间皆安”| 年终总结
    Oracle
    Linux安装
    线程池
    AutoJS
    VSCode
    c++ 解析yaml文件
    管道: 哪些命令能直接从管道的输出中读取?
    K8S 集群部署
    Android项目实战(六十一):pdf文件用图片方式预览
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229559.html
Copyright © 2020-2023  润新知