BZOJ 3223 文艺平衡树

Posted on 2016-03-22 21:35  ziliuziliu  阅读(228)  评论(0编辑  收藏  举报

嘿嘿嘿。splay模板题。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxv 100500
using namespace std;
int tree[maxv][3],size[maxv],fath[maxv],rev[maxv],n,m,l,r,root;
void pushup(int now)
{
    int ls=tree[now][1],rs=tree[now][2];
    size[now]=size[ls]+size[rs]+1;
}
void build(int left,int right,int father)
{
    if (left>right) return;
    int now=left;
    if (left==right)
    {
        size[now]=1;fath[now]=father;
        if (now<father) tree[father][1]=now;
        else tree[father][2]=now;
        return;
    }
    int mid=(left+right)>>1;now=mid;
    fath[now]=father;
    if (now<father) tree[father][1]=now;
    else tree[father][2]=now;
    build(left,mid-1,mid);
    build(mid+1,right,mid);
    pushup(now);
}
void pushdown(int now)
{
    if (rev[now]!=0)
    {
        swap(tree[now][1],tree[now][2]);
        rev[tree[now][1]]^=1;
        rev[tree[now][2]]^=1;
        rev[now]=0;
    }
}
int find(int rank,int now)
{
    pushdown(now);
    int ls=tree[now][1],rs=tree[now][2];
    if (size[ls]>=rank) return find(rank,ls);
    else if (rank>size[ls]+1) return find(rank-size[ls]-1,rs);
    else return now;
}
void rotate(int x,int &k)
{
    int y=fath[x],z=fath[y],l,r;
    if (tree[y][1]==x) l=1;else l=2;
    r=3-l;
    if (y==k) k=x;
    else
    {
        if (tree[z][1]==y) tree[z][1]=x;
        else tree[z][2]=x;
    }
    fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
    tree[y][l]=tree[x][r];tree[x][r]=y;
    pushup(y);pushup(x);
}
void splay(int x,int &k)
{
    while (x!=k)
    {
        int y=fath[x],z=fath[y];
        if (y!=k) 
        {
            if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x,k);
            else rotate(y,k);
        }
        rotate(x,k);
    }
}
void rever(int left,int right)
{
    int x=find(left,root),y=find(right+2,root);
    splay(x,root);splay(y,tree[x][2]);
    int r=tree[y][1];rev[r]^=1;
}
int main()
{
    scanf("%d%d",&n,&m);
    root=(n+3)>>1;
    build(1,n+2,0);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        rever(l,r);
    }
    for (int i=2;i<=n+1;i++)
        printf("%d ",find(i,root)-1);
    return 0;
}