题目背景

这是一道经典的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

说明

\(n, m \leq 100000\)

思路见注释。

代码:

#include<iostream>
#include<cstdio>
#define maxn 200001
using namespace std;
inline int qread() {
char c=getchar();int num=0,f=1;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) num=num*10+c-'0';
return num*f;
}
struct tree {
int ch[2];
int ff,v,size,lazy;
void init(int x,int fa) {
ff=ch[0]=ch[1]=0;
size=1;
v=x;
ff=fa;
}
} t[maxn];
int n,root,m,tot;
inline void pushup(int x) {
t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+1;
}
inline void pushdown(int x) {
if(t[x].lazy) {
t[t[x].ch[0]].lazy^=1;
t[t[x].ch[1]].lazy^=1;
t[x].lazy=0;
swap(t[x].ch[0],t[x].ch[1]);
}
}
void rotate(int x) {
int y=t[x].ff; //x的父亲 。
int z=t[y].ff; //x的爷爷。
int k=t[y].ch[1]==x; //x是y的哪一个儿子。
t[z].ch[t[z].ch[1]==y]=x; //z的原来的y的位置变为x。
t[x].ff=z; //x的父亲变为z。
t[y].ch[k]=t[x].ch[k^1]; //x的与x原来在y的相对的那个儿子变成y的儿子。
t[t[x].ch[k^1]].ff=y; //更新父节点。
t[x].ch[k^1]=y; //x的与x原来相对位置的儿子变成y。
t[y].ff=x; //更新父节点。
pushup(y);
pushup(x);
}
inline void splay(int x,int goal) { //将x转为goal的儿子,若x为0,则旋转为根。
while(t[x].ff!=goal) { //一直转到x成为goal的儿子。
int y=t[x].ff,z=t[y].ff; //父节点祖父节点。
if(z!=goal)
(t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y); //分情况。
rotate(x); //无论什么情况都要最后旋转x。
}
if(!goal) //若goal为0,则更新x为根节点。
root=x;
}
inline void insert(int x) {
int u=root,ff=0;
while(u) ff=u,u=t[u].ch[x>t[u].v];
u=++tot;
if(ff) t[ff].ch[x>t[ff].v]=u;
t[u].init(x,ff);
splay(u,0);
}
inline int kth(int k) {
int u=root;
while(1) {
pushdown(u);
if(t[t[u].ch[0]].size>=k) u=t[u].ch[0];
else if(t[t[u].ch[0]].size+1==k) return u;
else k-=t[t[u].ch[0]].size+1,u=t[u].ch[1];
}
}
void write(int u) {
pushdown(u);
if(t[u].ch[0]) write(t[u].ch[0]);
if(t[u].v>1&&t[u].v<n+2) printf("%d ",t[u].v-1);
if(t[u].ch[1]) write(t[u].ch[1]);
}
inline void work(int l,int r) {
l=kth(l);
r=kth(r+2);
splay(l,0);
splay(r,l);
t[t[t[root].ch[1]].ch[0]].lazy^=1;
}
int main() {
n=qread(),m=qread();
for(int i=1; i<=n+2; ++i) insert(i);
while(m--) {
int l=qread(),r=qread();
work(l,r);
}
write(root);
printf("\n");
return 0;
}

洛谷 P3391【模板】文艺平衡树(Splay)的更多相关文章

  1. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  2. 【洛谷P3391】文艺平衡树——Splay学习笔记(二)

    题目链接 Splay基础操作 \(Splay\)上的区间翻转 首先,这里的\(Splay\)维护的是一个序列的顺序,每个结点即为序列中的一个数,序列的顺序即为\(Splay\)的中序遍历 那么如何实现 ...

  3. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  4. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  5. 洛谷 P3391 模板Splay

    #include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...

  6. 【洛谷P3369】普通平衡树——Splay学习笔记(一)

    二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...

  7. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

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

    题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...

  9. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

  10. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

随机推荐

  1. docker 制作本地镜像

    docker commit 55ddf8d62688 py_wb # 容器ID, 容器名称tag py_wb IP地址:5000/my-web:20180511 # 远程registory地址 我的镜 ...

  2. SPQuery DateTime 类型查询

    使用SPQuery查询时间,默认查询会忽略 时分秒,只检查日期,如果要检查时间,则必须添加 IncludeTimeValue='TRUE' 格式如下: <Where>    <Gt& ...

  3. SpringDataRedis操作Redis简单案例

    Jedis Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用.可以在Redis官网下载,当然还有一些开源爱好者提供的客户端,如Jredis.SRP等等,推荐使 ...

  4. Cunit编译安装

    1.  Examples/Makefile.am:26: to 'configure.ac' and run 'autoconf' again. configure.ac:211: error: re ...

  5. 实践作业3:白盒测试----简单介绍被测系统DAY4

    本次被测软件是高校学生信息管理系统,和上次黑盒测试选用一样的系统,这样做的好处在于我们对系统比较熟悉,而且可以更好的比较黑盒测试与白盒测试的区别,采用MySQL Workbench 6.3,在MyEc ...

  6. elasticsearch plugin

    bin/plugin -install de.spinscale/elasticsearch-plugin-suggest/0.90.5-0.9 plugin -install mobz/elasti ...

  7. brk/sbrk和mmap行为分析程序

    #include <stdio.h> #include <stdlib.h> #include <unistd.h> // #include <malloc. ...

  8. 如何恢复VS2013代码实时校验功能

      VS2013在某一天突然无法进行实时代码校验了,只有在编译的时候,错误列表才显示语法错误 怎么来解决这个问题呢?试试环境重置吧. 首先:打开工具菜单,选择“导入和导出设置”. 其次:可以先导出选定 ...

  9. POJ1062 昂贵的聘礼(带限制的spfa)

    Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低 ...

  10. ABP源码uml类图

    陆陆续续学习ABP框架有一段时间了,阳光铭睿的入门教程和HK Zhang的源码分析文章对我的学习帮助都很大.之所以会花这么大工夫去学习ABP.看ABP的源代码,一是因为本人对于DDD也非常有兴趣,AB ...