码迷,mamicode.com
首页 > 其他好文 > 详细

文艺平衡树(splay)

时间:2020-01-31 12:15:10      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:problem   lib   html   ons   efault   blank   htm   结果   描述   

文艺平衡树(luogu)

Description

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列。

其中需要提供以下操作:翻转一个区间,例如原有序序列是 5\ 4\ 3\ 2\ 15 4 3 2 1,翻转区间是 [2,4][2,4] 的话,结果是 5\ 2\ 3\ 4\ 15 2 3 4 1。

输入格式

第一行两个正整数 n,mn,m,表示序列长度与操作个数。序列中第 ii 项初始为 ii。
接下来 mm 行,每行两个正整数 l,rl,r,表示翻转的区间。

输出格式

输出一行 nn 个正整数,表示原始序列经过 mm 次变换后的结果。

Code

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N=100010,inf=999999999;
int sum,n,root,m,l,r,d[N],fa[N],size[N],s[N][2],v[N],tag[N];
inline int which(int x) 
{
    return x==s[fa[x]][0]?0:1;
}
inline void push_up(int g)
{
    if(g){
        size[g]=1;
        if(s[g][0]) size[g]+=size[s[g][0]];
        if(s[g][1]) size[g]+=size[s[g][1]];
    }
}
void built(int l,int r,int &g)
{
    if(l>r) return ;
    g=++sum;
    size[g]=1;
    int mid=(l+r)>>1;
    v[g]=d[mid];
    built(l,mid-1,s[g][0]);
    built(mid+1,r,s[g][1]);
    fa[s[g][0]]=fa[s[g][1]]=g;
    push_up(g);
}
inline void push_down(int g)
{
    if(g && tag[g]){
        tag[s[g][0]]^=1,tag[s[g][1]]^=1;
        swap(s[g][0],s[g][1]),tag[g]=0;
    }   
}
inline int find(int x)
{
    int now=root;
    while(1)
    {
        push_down(now);
        if(size[s[now][0]]>=x) now=s[now][0];
        else
        {
            x-=size[s[now][0]]+1;
            if(x>0) now=s[now][1];
            else return now;
        }
    }
}
inline void rotate(int x)
{
    int f=fa[x],oldf=fa[f];
    push_down(f),push_down(x);
    int w=which(x),ww=which(f);
    s[f][w]=s[x][w^1];
    fa[s[x][w^1]]=f;
    fa[f]=x,fa[x]=oldf;
    s[x][w^1]=f;
    if(oldf) s[oldf][s[oldf][1]==f]=x;
    push_up(f),push_up(x);
}
inline void splay(int x,int g)
{
    for(int i;(i=fa[x])!=g;rotate(x))
        if(fa[i]!=g) rotate(which(i)==which(x)?i:x);
    if(g==0) root=x;
}
inline void re(int l,int r)
{
    l=find(l-1),r=find(r+1);
    splay(l,0),splay(r,l);
    int pos=s[s[root][1]][0];
    tag[pos]^=1;
}
void dfs(int x)
{
    push_down(x);
    if(s[x][0]) dfs(s[x][0]);
    if(v[x]!=-inf && v[x]!=inf) printf("%d ",v[x]);
    if(s[x][1]) dfs(s[x][1]);
}
int main()
{
    scanf("%d%d",&n,&m);
    d[1]=-inf,d[n+2]=inf;
    for(int i=1;i<=n;i++) d[i+1]=i;
    built(1,n+2,root);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&l,&r);
        re(l+1,r+1);
    }
    dfs(root);
    return 0;
}

 

 

文艺平衡树(splay)

标签:problem   lib   html   ons   efault   blank   htm   结果   描述   

原文地址:https://www.cnblogs.com/hsez-cyx/p/12244750.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!