【BZOJ3223】文艺平衡树,Splay反转区间

传送门
写在前面:感觉身体被掏空
思路:不明
注意:打标记

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int tot,n,m,root,x,y;
bool mark[100010];
struct os
{
    int father,left,right,data,sz;
}a[200010];
void pushdown(int now)
{
    if (!mark[now]||!now) return;
    mark[now]=0;
    swap(a[now].left,a[now].right);
    if (a[now].left) mark[a[now].left]^=1;
    if (a[now].right) mark[a[now].right]^=1;
}
void ct(int now)
{
    a[now].sz=1+a[a[now].left].sz+a[a[now].right].sz;
}
void made(int x)
{
    a[++tot].data=x;
    a[tot].sz=1;
}
void rotate(int x,bool flag)
{
    int y=a[x].father;
    if (flag)
    {
        a[y].left=a[x].right;
        if (a[x].right) a[a[x].right].father=y;
        a[x].father=a[y].father;
        if(a[y].father)
        {
            if (a[a[y].father].left==y) a[a[y].father].left=x;
            else a[a[y].father].right=x;
        }
        a[y].father=x;
        a[x].right=y;
    }
    else
    {
        a[y].right=a[x].left;
        if (a[x].left) a[a[x].left].father=y;
        a[x].father=a[y].father;
        if(a[y].father)
        {
            if (a[a[y].father].left==y) a[a[y].father].left=x;
            else a[a[y].father].right=x;
        }
        a[y].father=x;
        a[x].left=y;
    }
    ct(y);
    ct(x);
}
void splay(int x,int goal)
{
    int y;
    while (a[x].father!=goal)
    {
        y=a[x].father;
        if (a[y].father==goal)
        {
            if (x==a[y].left) rotate(x,1);
            else rotate(x,0);
        }
        else if (y==a[a[y].father].left)
        {
            if (x==a[y].left) rotate(y,1);
            else rotate(x,0);
            rotate(x,1);
        }
        else
        {
            if (x==a[y].right) rotate(y,0);
            else rotate(x,1);
            rotate(x,0);
        }
    }
    if (!goal) root=x;
}
void insert(int x)
{
    if (!root) {made(x);root=tot;return;}
    int now=root;
    int flag=0;
    while (!flag)
    {
        a[now].sz++;
        if (a[now].data>x)
        {
            if (!a[now].left) made(x),a[now].left=tot,a[tot].father=now,flag=1;
            else now=a[now].left;
        }
        else
        {
            if (!a[now].right) made(x),a[now].right=tot,a[tot].father=now,flag=1;
            else now=a[now].right;
        }
    }
    splay(tot,0);
}
int Kth(int k)
{
    int now=root;
    while (now)
    {
        pushdown(now);
        if (a[a[now].left].sz+1==k) return now;
        if (a[a[now].left].sz>=k) now=a[now].left;
        else k-=(a[a[now].left].sz+1),now=a[now].right;
    }
}
main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<n+3;i++) insert(i);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        int l=Kth(x),r=Kth(y+2);
        splay(l,0);
        splay(r,root);
        mark[a[r].left]^=1;
    }
    for (int i=2;i<=n+1;i++) printf("%d ",a[Kth(i)].data-1);
}

你可能感兴趣的:(【BZOJ3223】文艺平衡树,Splay反转区间)