Treap模板

Treap

可持久化,多種區間操作

merge操作

int merge(int a, int b)
{
    if(!a || !b) return a+b;
    if(rnd(b)>=rnd(a)){
        l(b)=merge(a,l(b)); update(b); return b;
    } else {
        r(a)=merge(r(a),b); update(a); return a; 
    }
}

split操作

pii split(int o, int val)//按數值分
{
    if(!o) return pii(0,0);
    if(val>=val(o)){
        pii tmp=split(r(o),val);
        r(o)=tmp.first; update(o);
        return pii(o, tmp.second);
    } else {
        pii tmp=split(l(o),val);
        l(o)=tmp.second; update(o);
        return pii(tmp.first, o);
    }
}

模板題

[Tyvj 1728]普通平衡數


完整模板

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    #define File(x) "phs."#x
    #define For(i,s,e) for(int i=(s); i<=(e); i++)
    #define Rep(i,s,e) for(int i=(s); i>=(e); i--)
    using namespace std;

    const int N=30*1e5+10,inf=0x7fffffff;
    typedef pair<int,int> pii;
    struct TREAP{
        int l,r,val,size,rnd;
        #define l(x) T[x].l
        #define r(x) T[x].r
        #define val(x) T[x].val
        #define s(x) T[x].size
        #define rnd(x) T[x].rnd 
    }T[N];

    int root,len,ans,n;

    int addPoint(int val)
    {
        len++; val(len)=val; s(len)=1; r(len)=l(len)=0; rnd(len)=rand(); return len; 
    }
    void update(int o){ s(o)=s(l(o))+s(r(o))+1; }
    int merge(int a, int b)
    {
        if(!a || !b) return a+b;
        if(rnd(b)>=rnd(a)){
            l(b)=merge(a,l(b)); update(b); return b;
        } else {
            r(a)=merge(r(a),b); update(a); return a; 
        }
    }
    pii split(int o, int val)
    {
        if(!o) return pii(0,0);
        if(val>=val(o)){
            pii tmp=split(r(o),val);
            r(o)=tmp.first; update(o);
            return pii(o, tmp.second);
        } else {
            pii tmp=split(l(o),val);
            l(o)=tmp.second; update(o);
            return pii(tmp.first, o);
        }
    }
    void insert(int val)
    {
        pii tmp=split(root,val);
        root=merge(merge(tmp.first, addPoint(val)), tmp.second);
    }
    int del(int o, int val)
    {
        if(!o) return 0;
        if(val==val(o)) return merge(l(o), r(o));
        if(val>val(o)){
            r(o)=del(r(o),val); update(o);
        } else {
            l(o)=del(l(o),val); update(o);
        }
        return o;
    }
    int find(int val)
    {
        pii tmp=split(root, val-1); int ret=s(tmp.first)+1; root=merge(tmp.first,tmp.second);
        return ret;
    }
    int findx(int o, int x)
    {
        if(!o) return 0;
        if(s(l(o))+1==x) return val(o);
        if(s(l(o))>=x) return findx(l(o),x);
        return findx(r(o), x-s(l(o))-1);
    }
    void pre(int val, int o)
    {
        if(!o) return;
        if(val(o)<val) ans=val(o),pre(val,r(o));
        else pre(val,l(o));
    }
    void next(int val, int o)
    {
        if(!o) return;
        if(val(o)>val) ans=val(o),next(val,l(o));
        else next(val, r(o));
    }

    int main()
    {
        freopen(File(in),"r",stdin);
        freopen(File(out),"w",stdout);

    //  ios::sync_with_stdio(false);

        cin>>n;
        while(n--)
        {
            int opt,x; scanf("%d %d",&opt,&x);
            switch(opt)
            {
                case 1: insert(x); break;
                case 2: root=del(root,x); break;
                case 3: printf("%d\n",find(x)); break;
                case 4: printf("%d\n",findx(root,x)); break;
                case 5: pre(x, root); printf("%d\n",ans); break;
                case 6: next(x, root); printf("%d\n",ans); break;
            }
        }

        return 0;
    }
發佈了23 篇原創文章 · 獲贊 18 · 訪問量 2940
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章