无旋Treap

Posted 探险家Mr.H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无旋Treap相关的知识,希望对你有一定的参考价值。

听说NOI系列考试不能用平板电视

所以手写了一个无旋Treap 有可能之后进化成fhq Treap

谁知道呢

bzoj3224

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define P pair<int,int>
using namespace std;
inline int ran()
{
    static int seed=19260817;
    seed+=(seed<<2)+1;
    return seed;
}
int op,n,x;
struct Treap
{
    struct Treapnode
    {
        int ls,rs,val,size;
        int rnd;
    }tr[100010];
    int rt,sz;
    inline void update(int id){tr[id].size=tr[tr[id].ls].size+tr[tr[id].rs].size+1;}
    inline int merge(int a,int b)
    {
        if(a==0 || b==0)return a+b;
        if(tr[a].rnd<tr[b].rnd)return tr[a].rs=merge(tr[a].rs,b),update(a),a;
        else return tr[b].ls=merge(a,tr[b].ls),update(b),b;
    }
    inline P split(int a,int n)
    {
        if(n==0)return make_pair(0,a);
        int L=tr[a].ls,R=tr[a].rs;
        if(n==tr[L].size)return tr[a].ls=0,update(a),make_pair(L,a);
        if(n==tr[L].size+1) return tr[a].rs=0,update(a),make_pair(a,R);
        if(n<tr[L].size)
        {
            P tmp=split(L,n);
            return tr[a].ls=tmp.second,update(a),make_pair(tmp.first,a);
        }
        P tmp=split(R,n-tr[L].size-1);
        return tr[a].rs=tmp.first,update(a),make_pair(a,tmp.second);
    }
    inline int rank(int x,int rt)
    {
        int ans=0,tmp=2147483233;
        while(rt)
        {
            if(x==tr[rt].val)tmp=min(tmp,ans+tr[tr[rt].ls].size+1);
            if(x>tr[rt].val)ans+=tr[tr[rt].ls].size+1,rt=tr[rt].rs;
            else rt=tr[rt].ls;
        }
        return tmp==2147483233?ans:tmp;
    }
    inline int find(int x,int id)
    {
        while(1)
        {
            if(tr[tr[id].ls].size==x-1)return tr[id].val;
            if(tr[tr[id].ls].size>x-1)id=tr[id].ls;
            else x=x-tr[tr[id].ls].size-1,id=tr[id].rs;
        }
    }
    inline int pre(int x,int k)
    {
        int ans=-(int)1e9;
        while(k)
        {
            if(tr[k].val<x)ans=max(ans,tr[k].val),k=tr[k].rs;
            else k=tr[k].ls;
        }
        return ans;
    }
    inline int suf(int x,int k)
    {
        int ans=(int)1e9;
        while(k)
        {
            if(tr[k].val>x)ans=min(ans,tr[k].val),k=tr[k].ls;
            else k=tr[k].rs;
        }
        return ans;
    }
    inline void add(int x)
    {
        int k=rank(x,rt);
        P tmp=split(rt,k);
        tr[++sz].val=x;
        tr[sz].rnd=ran();
        tr[sz].size++;
        rt=merge(tmp.first,sz);
        rt=merge(rt,tmp.second);
    }
    inline void del(int x)
    {
        int k=rank(x,rt);
        P t1=split(rt,k);
        P t2=split(t1.first,k-1);
        rt=merge(t2.first,t1.second);
    }
}treap;
int main()
{
    treap.rt=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&op,&x);
        if(op==1)treap.add(x);
        else if(op==2)treap.del(x);
        else if(op==3)printf("%d\n",treap.rank(x,treap.rt));
        else if(op==4)printf("%d\n",treap.find(x,treap.rt));
        else if(op==5)printf("%d\n",treap.pre(x,treap.rt));
        else printf("%d\n",treap.suf(x,treap.rt));
    }
    return 0;
}

 

以上是关于无旋Treap的主要内容,如果未能解决你的问题,请参考以下文章

[代码] bzoj 1500 维修数列(无旋treap)

[代码] bzoj 3224 普通平衡树(无旋treap)

无旋Treap

无旋Treap

模板 - 数据结构 - 无旋Treap / FHQ Treap

[您有新的未分配科技点]无旋treap:从好奇到入门(例题:bzoj3224 普通平衡树)