BZOJ3223 文艺平衡树(splay)

Posted Styx-ferryman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3223 文艺平衡树(splay)相关的知识,希望对你有一定的参考价值。

题目背景

这是一道经典的Splay模板题——文艺平衡树。

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入输出格式

输入格式:
第一行为n,m n表示初始序列有n个数,这个序列依次是 (1,2, \cdots n-1,n)(1,2,?n−1,n) m表示翻转操作次数

接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n 1≤l≤r≤n

输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果

输入输出样例

输入样例#1:
5 3
1 3
1 3
1 4
输出样例#1: 
4 3 2 1 5

题解:打标记的splay!调了一个上午终于调出来了!继续挖坑~

代码如下:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
using namespace std;

struct Splay
{
    int key[N],son[N][2],size[N],fa[N],tag[N],rt,sz,pos;
    inline void push_up(int x)
    {
        size[x]=size[son[x][0]]+size[son[x][1]]+1;
    }
    inline void push_down(int x)
    {
        if(!tag[x])
        {
            return;
        }
        tag[x]=0;
        tag[son[x][0]]^=1;
        tag[son[x][1]]^=1;
        swap(son[x][0],son[x][1]);
    }
    inline void rotate(int x)
    {
        int y=fa[x],z=fa[y],k=(son[y][0]==x);
        son[z][son[z][1]==y]=x;
        fa[x]=z;
        son[y][!k]=son[x][k];
        fa[son[x][k]]=y;
        son[x][k]=y;
        fa[y]=x;
        push_up(y);
    }
    inline void splay(int x,int goal)
    {
        for(push_down(x); fa[x]!=goal; rotate(x))
        {
            int y=fa[x],z=fa[y];
            if(z!=goal)
            {
                (son[y][0]==x)^(son[z][0]==y)?rotate(x):rotate(y);
            }
        }
        push_up(x);
        if(!goal)
        {
            rt=x;
        }
    }
    inline int kth(int k)
    {
        for(int x=rt;;)
        {
            push_down(x);
            int y=son[x][0];
            if(k>size[y]+1)
            {
                k-=size[y]+1;
                x=son[x][1];
            }
            else
            {
                if(k>size[y])
                {
                    return x;
                }
                else
                {
                    x=y;
                }
            }
        }
    }
    inline void reverse(int l,int r)
    {
        if(l>r)
        {
            swap(l,r);
        }
        int x=kth(l),y=kth(r+2);
        splay(x,0);
        splay(y,x);
        tag[son[y][0]]^=1;
    }
    inline int build(int *a,int father,int l,int r)
    {
        if(l>r)
        {
            return 0;
        }
        int mid=(l+r)>>1,x=++sz;
        fa[x]=father;
        key[x]=a[mid];
        son[x][0]=build(a,x,l,mid-1);
        son[x][1]=build(a,x,mid+1,r);
        push_up(x);
        return x;
    }
    inline void put(int x)
    {
        push_down(x);
        if(son[x][0])
        {
            put(son[x][0]);
        }
        if(key[x]>-1e9&&key[x]<1e9)
        {
            printf("%d ",key[x]);
        }
        if(son[x][1])
        {
            put(son[x][1]);
        }
    }
} splay1;

int main()
{
    int n,m,l,r,a[100010];

    scanf("%d%d",&n,&m);
    for(int i=2; i<=n+1; i++)
    {
        a[i]=i-1;
    }
    a[1]=-1e9;
    a[n+2]=1e9;
    splay1.rt=splay1.build(a,0,1,n+2);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d",&l,&r);
        splay1.reverse(l,r);
    }
    splay1.put(splay1.rt);
}

 

以上是关于BZOJ3223 文艺平衡树(splay)的主要内容,如果未能解决你的问题,请参考以下文章

JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树

[BZOJ3223] [Tyvj1729] 文艺平衡树 (splay)

BZOJ3223文艺平衡树(splay)

[Bzoj3223][Tyvj1729] 文艺平衡树(splay/无旋Treap)

bzoj3223: Tyvj 1729 文艺平衡树(splay翻转操作)

[bzoj3223]文艺平衡树(splay区间反转模板)