非旋式Treap

作者: fo0Old | 来源:发表于2018-09-21 13:33 被阅读0次

    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

        本文链接:https://www.haomeiwen.com/subject/pymanftx.html