前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >洛谷P3391 【模板】文艺平衡树(Splay)

洛谷P3391 【模板】文艺平衡树(Splay)

作者头像
attack
发布2018-04-11 14:53:14
8080
发布2018-04-11 14:53:14
举报

题目背景

这是一道经典的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 n1≤l≤r≤n

输出格式:

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

输入输出样例

输入样例#1

代码语言:javascript
复制
5 3
1 3
1 3
1 4

输出样例#1: 

代码语言:javascript
复制
4 3 2 1 5

说明

n, m \leq 100000n,m≤100000

补一发splay版

以下标建一棵树

每次按照规则旋转就好

代码语言:javascript
复制
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN=1e5+10;
const int maxn=0x7fffff;
inline char nc()
{
    static char buf[MAXN],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    char c=nc();int x=0,f=1;
    while(c<'0'||c>'9'){c=nc();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
    return x*f;
}
int n,m;
struct node
{
    int tot,fa,ch[2];
    bool rev;
}tree[MAXN];
int tot,point;
int root;
int PosL,PosR;
inline void connect(int x,int fa,bool how)
{
    tree[x].fa=fa;
    tree[fa].ch[how]=x;
}
inline void update(int k)
{
    tree[k].tot=tree[tree[k].ch[0]].tot+tree[tree[k].ch[1]].tot+1;
}
inline int BuildTree(int l,int r)
{
    if(l>r) return 0;
    int mid=(l+r)>>1;
    connect(BuildTree(l,mid-1),mid,0);
    connect(BuildTree(mid+1,r),mid,1);
    tree[mid].rev=0;
    update(mid);
    return mid;
}
inline bool ident(int x)
{
    return tree[tree[x].fa].ch[1]==x;
}
inline void pushdown(int x)
{
    if(tree[x].rev)
    {
        swap(tree[x].ch[0],tree[x].ch[1]);
        tree[tree[x].ch[0]].rev^=1;
        tree[tree[x].ch[1]].rev^=1;    
        tree[x].rev=0;
    }
}
inline void rotate(int X)
{
   // pushdown(tree[X].fa);pushdown(X);
    int Y=tree[X].fa;
    if(Y==root)    root=X;
    int R=tree[Y].fa;
    bool Yson=ident(X);
    bool Rson=ident(Y);
    int B=tree[X].ch[Yson^1];
    connect(B,Y,Yson);
    connect(Y,X,Yson^1);
    connect(X,R,Rson);
    update(Y);update(X);
}
inline void splay(int x,int to)
{
    while(tree[x].fa!=to)
    {
        if(tree[tree[x].fa].fa==to)        rotate(x);
        else if(ident(x)==ident(tree[x].fa)) rotate(tree[x].fa),rotate(x);
        else rotate(x),rotate(x);
    }
    update(x);
}
inline int find(int x)
{
    int now=root;x--;
    pushdown(now);
    while(x!=tree[tree[now].ch[0]].tot)
    {
        if (tree[tree[now].ch[0]].tot<x) x-=tree[tree[now].ch[0]].tot+1,now=tree[now].ch[1];
          else now=tree[now].ch[0];
        pushdown(now);
    }
    return now;
}
void print(int now)
{
    if(!now)    return ;
    pushdown(now);
    print(tree[now].ch[0]);
    if(now!=1&&now!=n+2) printf("%d ",now-1);
    print(tree[now].ch[1]);
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif  
    n=read(),m=read();
    root=BuildTree(1,n+2);
    for(int i=1;i<=m;i++)
    {
        int l=read(),r=read();
        PosL=find(l);
        splay(PosL,0);
        PosR=find(r+2);
        splay(PosR,root);
        tree[tree[PosR].ch[0]].rev^=1;
    }
    print(root);
}
                    
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-11-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目背景
  • 题目描述
  • 输入输出格式
  • 输入输出样例
  • 说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档