[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;
}

 

posted @ 2017-04-23 19:25  FallDream  阅读(178)  评论(0编辑  收藏  举报