非旋式Treap

SuperMemo

struct Treap
{
    #define fa(x) t[x].nex[0]
    #define ls(x) t[x].nex[1]
    #define rs(x) t[x].nex[2]

    const static int __=2e5+5;
    static int rd()
    {
        static int seed=2333;
        return seed=seed*482711ll%2147483647;
    }

    struct node
    {
        ll val,minn,ad;
        int nex[3],siz,key;
        bool rev;

        void set(ll v)
        {
            val=minn=v;
        }

        void operator+=(const node &b)
        {
            siz+=b.siz;
            minn=min(minn,b.minn);
        }

        void putrev(){rev=!rev;}

        void putadd(ll v)
        {
            val+=v,minn+=v,ad+=v;
        }

        void clear()
        {
            key=rd();
            rev=false;
            siz=1,ad=0;
            mem(nex,0);
        }
    }t[__];

    int root;

    void pushup(int x)
    {
        t[x].siz=1,t[x].minn=t[x].val;
        if(ls(x))t[x]+=t[ls(x)];
        if(rs(x))t[x]+=t[rs(x)];
    }

    void pushdown(int x)
    {
        if(t[x].rev)
        {
            swap(ls(x),rs(x));
            if(ls(x))t[ls(x)].putrev();
            if(rs(x))t[rs(x)].putrev();
            t[x].rev=0;
        }
        if(t[x].ad)
        {
            if(ls(x))t[ls(x)].putadd(t[x].ad);
            if(rs(x))t[rs(x)].putadd(t[x].ad);
            t[x].ad=0;
        }
    }

    struct memory
    {
        static const int __=1e5+5;
        int idx,trash[__];

        int get()
        {
            if(trash[0])return trash[trash[0]--];
            return ++idx;
        }

        void del(int x){trash[++trash[0]]=x;}

        void clear(){idx=trash[0]=0;}
    }M;

    Treap() {clear();}

    void up(int x)
    {
        for(;x;x=fa(x))pushup(x);
    }

    pii split(int x,int p)
    {
        int rt[3]={0},now[3]={0};
        for(int siz1=0;x;)
        {
            pushdown(x);
            int k=(t[ls(x)].siz+1+siz1<=p)?1:2;
            if(!rt[k])rt[k]=x;
            else fa(t[now[k]].nex[3-k]=x)=now[k];
            if(k==1)siz1+=t[ls(x)].siz+1;
            now[k]=x,x=t[x].nex[3-k];
        }
        rs(now[1])=0,up(now[1]);
        ls(now[2])=0,up(now[2]);
        return mp(rt[1],rt[2]);
    }

    int merge(int x,int y)
    {
        if(!x || !y)return x?x:y;
        int rt[3]={0,x,y},z=0,d=0;
        while(rt[1] && rt[2])
        {
            int k=(t[rt[1]].key<=t[rt[2]].key)?1:2;
            if(!rt[1] || !rt[2])k=(rt[1]?1:2);
            pushdown(rt[k]);
            if(!rt[0])rt[0]=rt[k];
            else fa(t[z].nex[d]=rt[k])=z;
            z=rt[k],rt[k]=t[rt[k]].nex[d=3-k];
        }
        fa(t[z].nex[d]=rt[1]?rt[1]:rt[2])=z;
        up(z);
        return rt[0];
    }

    //a[p]后插入一个数p
    void insert(int p,ll v)
    {
        pii y=split(root,p);
        int x=M.get();
        t[x].clear();
        t[x].set(v);
        root=merge(merge(y.fi,x),y.se);
    }

    //删除a[p]
    void erase(int p)
    {
        pii x=split(root,p-1);
        pii y=split(x.se,1);
        root=merge(x.fi,y.se);
    }

    //a[l]……a[r] +val
    void add(int l,int r,ll v)
    {
        pii x=split(root,r);
        pii y=split(x.fi,l-1);
        t[y.se].putadd(v);
        root=merge(merge(y.fi,y.se),x.se);
    }

    //a[l]……a[r] -> a[r]……a[l]
    void reversal(int l,int r)
    {
        pii x=split(root,r);
        pii y=split(x.fi,l-1);
        t[y.se].putrev();
        root=merge(merge(y.fi,y.se),x.se);
    }

    //min(a[l]……a[r])
    ll get_min(int l,int r)
    {
        pii x=split(root,r);
        pii y=split(x.fi,l-1);
        ll v=t[y.se].minn;
        root=merge(merge(y.fi,y.se),x.se);
        return v;
    }

    //a[l]……a[r] -> a[r-k+1]……a[r]a[l]……a[r-k]
    void revolve(int l,int r,int k)
    {
        k=(k%(r-l+1)+(r-l+1))%(r-l+1);
        if(!k)return;
        pii x=split(root,r);
        pii y=split(x.fi,l-1);
        pii z=split(y.se,r-l+1-k);
        root=merge(merge(y.fi,merge(z.se,z.fi)),x.se);
    }

    void clear()
    {
        root=0;
        M.clear();
    }
}T;

你可能感兴趣的:(非旋式Treap)