洛谷.3369.[模板]普通平衡树(fhq Treap)

题目链接

第一次(2017.12.24):

#include<cstdio>
#include<cctype>
#include<algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=1e5+5,MAXIN=2e6;

char IN[MAXIN],*SS=IN,*TT=IN;
int size,sz[N],son[N][2],val[N],fix[N];
int New_Node(int v)
{
    sz[++size]=1, val[size]=v, fix[size]=rand();
    return size;
}
inline void Update(int rt)
{
    sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+1;
}
void Split(int rt,int v,int &x,int &y)
{
    if(!rt) x=y=0;
    else
    {
        if(val[rt]<=v) x=rt,Split(son[rt][1],v,son[rt][1],y);
        else y=rt,Split(son[rt][0],v,x,son[rt][0]);
        Update(rt);
    }
}
int Merge(int x,int y)
{
    if(!x||!y) return x+y;
    if(fix[x]<fix[y])
    {
        son[x][1]=Merge(son[x][1],y);
        Update(x);
        return x;
        }
    else
    {
        son[y][0]=Merge(x,son[y][0]);
        Update(y);
        return y;
    }
}
int Kth(int rt,int k)
{
    while(1)
    {
        if(sz[son[rt][0]]+1==k) return rt;
        if(sz[son[rt][0]]<k) k-=sz[son[rt][0]]+1,rt=son[rt][1];
        else rt=son[rt][0];
        }
}
int Find(int rt,int w)
{
    while(son[rt][w]) rt=son[rt][w];
    return val[rt];
}
inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}

int main()
{
    int q=read(),opt,v,x,y,z,root=0;
    while(q--)
    {
        opt=read(),v=read();
        switch(opt)
        {
            case 1: Split(root,v,x,y),root=Merge(Merge(x,New_Node(v)),y);//Insert
                    break;
            case 2: Split(root,v,x,z),Split(x,v-1,x,y);//Delete
                    y=Merge(son[y][0],son[y][1]),root=Merge(Merge(x,y),z);
                    break;
            case 3: Split(root,v-1,x,y),printf("%d\n",sz[x]+1);//Get_Rank
                    root=Merge(x,y);
                    break;
            case 4: printf("%d\n",val[Kth(root,v)]);//Rank
                    break;
            case 5: Split(root,v-1,x,y),printf("%d\n",val[Kth(x,sz[x])]);//printf("%d\n",Find(x,1));
                    root=Merge(x,y);//Precursor
                    break;
            case 6: Split(root,v,x,y),printf("%d\n",val[Kth(y,1)]);//printf("%d\n",Find(y,0));
                    root=Merge(x,y);//Successor
                    break;
        }
    }

    return 0;
}

第二次(2017.3.24):差不了太多。

//尴尬 rank没加1 
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e5+5;

struct fhq_Treap
{
    #define lson son[rt][0]
    #define rson son[rt][1]

    int tot,son[N][2],val[N],fix[N],sz[N];
    inline int New_Node(int v){
        sz[++tot]=1, fix[tot]=rand(), val[tot]=v;
        return tot;
    }
    inline void Update(int rt){
        sz[rt]=sz[lson]+sz[rson]+1;
    }
    int Merge(int x,int y)
    {
        if(!x||!y) return x^y;
        if(fix[x]<fix[y])
        {
            son[x][1]=Merge(son[x][1],y);
            Update(x);
            return x;
        }
        else
        {
            son[y][0]=Merge(x,son[y][0]);
            Update(y);
            return y;
        }
    }
    void Split(int rt,int v,int &x,int &y)
    {
        if(!rt) x=y=0;
        else{
            if(val[rt]<=v) x=rt,Split(rson,v,rson,y);
            else y=rt,Split(lson,v,x,lson);
            Update(rt);
        }
    }
    int Kth(int k,int rt)
    {
        while(1)
        {
            if(sz[lson]<k && sz[lson]+1==k) return val[rt];
            if(sz[lson]<k) k-=sz[lson]+1,rt=rson;
            else rt=lson;
        }
    }
    int Find(int rt,int w)
    {
        while(son[rt][w]) rt=son[rt][w];
        return val[rt];
    }
}t;
inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}

int main()
{
    int q=read(),opt,val,x,y,z,root=0;
    while(q--)
    {
        switch(opt=read(),val=read(),opt)
        {
            case 1: t.Split(root,val,x,y),root=t.Merge(t.Merge(x,t.New_Node(val)),y);
                    break;
            case 2: t.Split(root,val,x,z),t.Split(x,val-1,x,y),
                    y=t.Merge(t.son[y][0],t.son[y][1]),root=t.Merge(t.Merge(x,y),z);
                    break;
            case 3: t.Split(root,val-1,x,y),printf("%d\n",t.sz[x]+1),root=t.Merge(x,y);
                    break;
            case 4: printf("%d\n",t.Kth(val,root));
                    break;
            case 5: t.Split(root,val-1,x,y),printf("%d\n",t.Find(x,1)/*t.Kth(sz[x],x)*/),root=t.Merge(x,y);
                    break;
            case 6: t.Split(root,val/*以val分..*/,x,y),printf("%d\n",t.Find(y,0)),root=t.Merge(x,y);
                    break;
        }
    }
    return 0;
}

第三次写(2018.4.4):

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e5+5;

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
namespace fhq_Treap
{
    #define lson son[rt][0]
    #define rson son[rt][1]

    int tot,fa[N],son[N][2],sz[N],val[N],fix[N];
    inline int New_Node(int v){
        fix[++tot]=rand(), val[tot]=v, sz[tot]=1;
        return tot;
    }
    inline void Update(int rt){
        sz[rt]=sz[lson]+sz[rson]+1;
    }
    void Split(int rt,int v,int &x,int &y)
    {
        if(!rt) x=y=0;
        else{
            if(val[rt]<=v) x=rt,Split(rson,v,rson,y);//val[rt] not val[x]..
            else y=rt,Split(lson,v,x,lson);
            Update(rt);
        }
    }
    int Merge(int x,int y)
    {
        if(!x||!y) return x^y;
        if(fix[x]<fix[y]){
            son[x][1]=Merge(son[x][1],y), Update(x);
            return x;
        }
        else{
            son[y][0]=Merge(x,son[y][0]), Update(y);
            return y;
        }
    }
    int Rank(int k,int rt)
    {
        while(1)
        {
            if(sz[lson]+1==k) return rt;
            if(sz[lson]<k) k-=sz[lson]+1,rt=rson;
            else rt=lson;
        }
    }
    int Find(int rt,int w)
    {
        while(son[rt][w]) rt=son[rt][w];
        return rt;
    }
}
using namespace fhq_Treap;

int main()
{
    int n=read(),opt,v,x,y,z,root=0;
    while(n--)
        switch(opt=read(),v=read(),opt)
        {
            case 1: Split(root,v,x,y),x=Merge(x,New_Node(v)),root=Merge(x,y);
                    break;
            case 2: Split(root,v,x,z),Split(x,v-1,x,y),y=Merge(son[y][0],son[y][1]),root=Merge(Merge(x,y),z);
                    break;
            case 3: Split(root,v-1,x,y),printf("%d\n",sz[x]+1),root=Merge(x,y);
                    break;
            case 4: printf("%d\n",val[Rank(v,root)]);
                    break;
            case 5: Split(root,v-1,x,y),printf("%d\n",val[Find(x,1)]),root=Merge(x,y);
                    break;
            case 6: Split(root,v,x,y),printf("%d\n",val[Find(y,0)]),root=Merge(x,y);
                    break;
        }
    return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/8431909.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值