HYSBZ 3223 Tyvj 1729 文艺平衡树

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3223

带翻转的splay 只需要把l-1提到根位置,r+1提到根的右子树,那么r+1的左子树就是[l,r] 

对反转次数打标记

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int N=1e5+5;
const int inf=0x3f3f3f3f;
int n,m;
int f[N],ch[N][2],mark[N],sz[N],key[N];
int root,tot;
int a[N];
inline int get(int x)
{
    return ch[f[x]][1]==x;
}
inline void pushup(int x)
{
    sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
}
void pushdown(int x)
{
    if (x&&mark[x])
    {
        mark[ch[x][0]]^=1;
        mark[ch[x][1]]^=1;
        swap(ch[x][0],ch[x][1]);
        mark[x]=0;
    }
}
int build(int l,int r,int fa)
{
    if (l>r) return 0;
    int mid=(l+r)>>1;
    int now=++tot;
    f[now]=fa;key[now]=a[mid];mark[now]=0;
    ch[now][0]=build(l,mid-1,now);
    ch[now][1]=build(mid+1,r,now);
    pushup(now);
    return now;
}
int Find(int x)
{
    int now=root;
    while(1)
    {
        pushdown(now);
        if (x<=sz[ch[now][0]])
            now=ch[now][0];
        else
        {
            x=x-sz[ch[now][0]]-1;
            if (!x) return now;
            now=ch[now][1];
        }
    }
}
void Rotate(int x)
{
    pushdown(f[x]);
    pushdown(x);
    int fa=f[x],ff=f[fa],kind=get(x);
    ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
    ch[x][kind^1]=fa;f[fa]=x;
    f[x]=ff;
    if (ff)
        ch[ff][ch[ff][1]==fa]=x;
    pushup(fa);
    pushup(x);
}
void splay(int x,int y)
{
    for(int fa;(fa=f[x])!=y;Rotate(x))
        if (f[fa]!=y)
            Rotate((get(x)==get(fa))?fa:x);
    if (y==0) root=x;
}
void out(int now)
{
    pushdown(now);
    if (ch[now][0]) out(ch[now][0]);
    if (key[now]!=inf&&key[now]!=-inf)
        printf("%d ",key[now]);
    if (ch[now][1]) out(ch[now][1]);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(sz,0,sizeof(sz));
        tot=0;
        a[1]=-inf;a[n+2]=inf;
        for(int i=1;i<=n;i++)
            a[i+1]=i;
        root=build(1,n+2,0);
        int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            // x-1 y+1 还有-inf 所以就是x-1+1 y+1+1
            int xx=Find(x);
            int yy=Find(y+2);
            splay(xx,0);
            splay(yy,xx);
            mark[ch[ch[root][1]][0]]^=1;
        }
        out(root);
        printf("\n");
    }
    return 0;
}
  

  

posted @ 2017-08-18 15:57  BK_201  阅读(145)  评论(0编辑  收藏  举报