• 「模板」 FHQ_Treap


    「模板」 FHQ_Treap

    <题目链接>


    我也是偶然发现我还没发过FHQ_Treap的板子。

    那就发一波吧。

    这个速度实在不算快,但是不用旋转,并且好写

    更重要的是,Splay 可以做的事情它都可以做!比如区间操作,以及LCT相关…

    而且它还可以可持久化!(虽然目前还没有学)

    Capella 认为,不涉及区间操作时,用快一些的平衡树(SBT/Treap/替罪羊...)较好,涉及区间操作而又不想写大量代码的话,FHQ_Treap 不失为一种极好的选择。

    下一篇写 FHQ_Treap 的区间操作。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    const int MAXN=100010;
    int n;
    class FHQ_Treap
    {
        public:
            int rt;
            FHQ_Treap(void)
            {
                rt=cnt=0;
                memset(a,0,sizeof a);
                memset(s,0,sizeof s);
            }
            void Insert(int x)
            {
                int l=0,r=0,t=0;
                MakeNode(t,x),Split(rt,x,l,r);
                Merge(l,l,t),Merge(rt,l,r);
            }
            void Erase(int x)
            {
                int l=0,r=0,t=0;
                Split(rt,x,l,r),Split(l,x-1,l,t);
                Merge(t,s[t].c[0],s[t].c[1]),Merge(l,l,t),Merge(rt,l,r);
            }
            int Rank(int x)
            {
                int l=0,r=0,ans;
                Split(rt,x-1,l,r),ans=s[l].size+1,Merge(rt,l,r);
                return ans;
            }
            int Find(int i,int x)
            {
                int t;
                while(x!=(t=s[s[i].c[0]].size+1))
                    if(x<t)
                        i=s[i].c[0];
                    else
                        x-=t,i=s[i].c[1];
                return s[i].v;
            }
            int Pre(int x)
            {
                int l=0,r=0,ans;
                Split(rt,x-1,l,r),ans=Find(l,s[l].size),Merge(rt,l,r);
                return ans;
            }
            int Next(int x)
            {
                int l=0,r=0,ans;
                Split(rt,x,l,r),ans=Find(r,1),Merge(rt,l,r);
                return ans;
            }
        private:
            bool a[MAXN];
            int cnt;
            struct node
            {
                int v,p,size,c[2];
            }s[MAXN];
            int Random(void)
            {
                int x;
                while(a[x=rand()%MAXN]);
                a[x]=1;
                return x;
            }
            void Update(int i)
            {
                s[i].size=s[s[i].c[0]].size+s[s[i].c[1]].size+1;
            }
            void MakeNode(int &i,int x)
            {
                s[i=++cnt].v=x,s[i].p=Random(),s[i].size=1;
            }
            void Split(int i,int x,int &l,int &r)
            {
                if(!i)
                {
                    l=r=0;
                    return;
                }
                else if(x<s[i].v)
                    Split(s[r=i].c[0],x,l,s[i].c[0]);
                else
                    Split(s[l=i].c[1],x,s[i].c[1],r);
                Update(i);
            }
            void Merge(int &i,int l,int r)
            {
                if(!l || !r)
                {
                    i=l|r;
                    return;
                }
                else if(s[l].p>s[r].p)
                    Merge(s[i=l].c[1],s[l].c[1],r);
                else
                    Merge(s[i=r].c[0],l,s[r].c[0]);
                Update(i);
            }
    }T;
    int main(int argc,char *argv[])
    {
        srand((unsigned)time(NULL));
        scanf("%d",&n);
        for(int i=1,opt,x;i<=n;++i)
        {
            scanf("%d %d",&opt,&x);
            switch(opt)
            {
                case 1:
                    T.Insert(x);
                    break;
                case 2:
                    T.Erase(x);
                    break;
                case 3:
                    printf("%d
    ",T.Rank(x));
                    break;
                case 4:
                    printf("%d
    ",T.Find(T.rt,x));
                    break;
                case 5:
                    printf("%d
    ",T.Pre(x));
                    break;
                case 6:
                    printf("%d
    ",T.Next(x));
                    break;
            }
        }
        return 0;
    }
    

    谢谢阅读。

  • 相关阅读:
    git操作
    计算天数
    web小结~2019.3.24
    数据统计值的计算+PYTHON
    python~序列类型及操作
    一个日期加上若干天后是什么日期
    完数与盈数
    分段函数
    求最大最小
    D进制的A+B
  • 原文地址:https://www.cnblogs.com/Capella/p/8502857.html
Copyright © 2020-2023  润新知