bzoj 3233 文艺平衡树 (splay 区间翻转)

题目

思路:splay区间翻转的模板

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int inf=0x3f3f3f3f;
int size[MAXN],key[MAXN],f[MAXN],ch[MAXN][2],lazy[MAXN];
int a[MAXN];
int sz,root;
int n,m;
bool get(int x)
{
    return ch[f[x]][1]==x;
}
void update(int x)
{
        size[x]=1;
        if(ch[x][0])size[x]+=size[ch[x][0]];
        if(ch[x][1])size[x]+=size[ch[x][1]];
}
void pushdown(int x)
{
    if(lazy[x]&&x)
    {
        lazy[ch[x][0]]^=1;
        lazy[ch[x][1]]^=1;
        swap(ch[x][0],ch[x][1]);
        lazy[x]=0;
    }
}
void rotate(int x)
{
    int old=f[x],oldf=f[old],whichx=get(x);
    pushdown(old),pushdown(x);
    ch[old][whichx]=ch[x][whichx^1];
    f[ch[old][whichx]]=old;
    ch[x][whichx^1]=old;
    f[old]=x;
    f[x]=oldf;
    if(oldf)
        ch[oldf][ch[oldf][1]==old]=x;
    update(old);
    update(x);
}
void splay(int x,int g)
{
    for(int fa;(fa=f[x])!=g;rotate(x))
        if(f[fa]!=g)
        rotate((get(x)==get(f[fa]))?fa:x);
    if(!g)root=x;
}
int find(int x)
{
    int now=root;
    while(1)
    {
        pushdown(now);
        if(x<=size[ch[now][0]])now=ch[now][0];
        else
        {
            x-=size[ch[now][0]]+1;
            if(!x)return now;
            now=ch[now][1];
        }
    }
}
int build(int l,int r,int x)
{
    if(l>r)return 0;
    int mid=(l+r)>>1;
    int now=++sz;
    key[now]=a[mid];
    f[now]=x;
    lazy[now]=0;
    ch[now][0]=build(l,mid-1,now);
    ch[now][1]=build(mid+1,r,now);
    update(now);
    return now;
}
void turn(int l,int r)
{
    l=find(l);
    r=find(r+2);
    splay(l,0);
    splay(r,l);
    pushdown(root);
    lazy[ch[ch[root][1]][0]]^=1;
}
void write(int now)
{
    pushdown(now);
    if(ch[now][0])write(ch[now][0]);
    if(key[now]!=-inf&&key[now]!=inf)printf("%d ",key[now]);
    if(key[ch[now][1]])write(ch[now][1]);
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n+1;i++)
        a[i]=i-1;
    a[1]=inf;
    a[n+2]=-inf;
    root=build(1,n+2,0);
    while(m--)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        turn(x,y);
    }
    write(root);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/imzxww/article/details/81255667