• [bzoj3223]Tyvj 1729 文艺平衡树


    来自FallDream的博客,未经允许,请勿转载,谢谢。


    一个序列,一开始是1到n,需要支持翻转区间,输出最后的结果。 n,m<=10^5

    splay/无旋Treap 

    补了一下无旋Treap  顺便yy了一下笛卡尔树的建法,然后lazytag的实现也挺好想的。

    #include<iostream>
    #include<cstdio>
    #define MN 100000
    #define Size(x) (x?x->sz:0)
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    inline int Ran()
    {
        static int x=23333;
        x^=(x<<13);x^=(x>>17);x^=(x<<5);
        return x;
    }
    struct Treap
    {
        Treap *l,*r;
        int sz,x,k;bool rev;
        Treap(){l=r=NULL;}
        Treap(int key){x=key;k=Ran();sz=1;l=r=NULL;}
        void update(){sz=Size(l)+Size(r)+1;}
        void pushdown()
        {
            if(rev)
            {
                l?l->rev^=1:0;
                r?r->rev^=1:0;
                rev^=1;swap(l,r);
            }
        }
    }*rt;
    typedef pair<Treap*,Treap*> D;
    int n,m,top=0;
    
    Treap* Merge(Treap*x,Treap*y)
    {
        if(!x)return y;
        if(!y)return x;
        if(x->k<y->k)
        {
            x->pushdown();
            x->r=Merge(x->r,y);
            return x->update(),x;
        }
        else
        {
            y->pushdown();
            y->l=Merge(x,y->l);
            return y->update(),y;
        }
    }
    
    D Split(Treap*x,int Rk)
    {
        if(!x) return D(NULL,NULL);
        D b;x->pushdown();
        if(Size(x->l)>=Rk)
        {
            b=Split(x->l,Rk);
            x->l=b.second;
            x->update();
            b.second=x;
        }
        else
        {
            b=Split(x->r,Rk-Size(x->l)-1);
            x->r=b.first;
            x->update();
            b.first=x;
        }
        return b;
    }
    
    Treap*q[MN+5],*a[MN+5],*last;
    Treap* build()
    {
        for(int i=1;i<=n;i++)
        {
            last=NULL;
            while(top&&a[i]->k>q[top]->k) q[top]->update(),last=q[top],q[top--]=NULL;
            if(top) q[top]->r=a[i];
            q[++top]=a[i];q[top]->l=last;
        }
        for(;top;--top) q[top]->update();
        return q[1];
    }
    
    void Dfs(Treap*x)
    {
        x->pushdown();
        if(x->l) Dfs(x->l);
        printf("%d ",x->x);
        if(x->r) Dfs(x->r);
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)a[i]=new Treap(i);
        rt=build();
        for(int i=1;i<=m;i++)
        {
            int l=read(),r=read();
            D a=Split(rt,l-1);
            D b=Split(a.second,r-l+1);
            b.first->rev^=1;
            rt=Merge(Merge(a.first,b.first),b.second);
        }
        Dfs(rt);
        return 0;
    }
  • 相关阅读:
    Activity的四种launchMode
    Activity及Intent
    关于android中PendingIntent.getBroadcase的注册广播
    C# Parallel用法
    用Parallel.For()和Parallel.For<TLocal>()方法实现并行运行迭代
    CursorAdapter中getView newView bindView异同
    Android四大组件之ContentProvider
    Android 自动换行流式布局的RadioGroup
    真机无法接收到android.provider.Telephony.SMS_RECEIVED的问题
    Wiz开发 定时器的使用与处理
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj3223.html
Copyright © 2020-2023  润新知