题目背景

这是一道经典的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. spring 3.1.13中新增的util @value注解,给类或方法注入值

    在spring 3.0以上版本中,可以通过使用@value,对一些如xxx.properties文件 ,进行键值对的注入,例子如下: 一.类变量注入 1 首先在applicationContext.x ...

  2. c++ 门面模式(Facade)

    门面模式是比较常用的一种设计模式,我们可能在无意中就会使用,门面模式就是用一个门面类来处理子系统的复杂关系,门面类简单的Api接口供客户端调用.用一个简单的演播室来表示. #include <i ...

  3. 30-懒省事的小明(priority_queue)

    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=55 懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   ...

  4. 数据库sql 开窗函数

    --本文采用Oracle数据库测试,前4个查询为一组,后2个查询为一组,每组前面的查询是为了推出最后的查询 --创建表,为了简化处理,字段类型都采用varcharcreate table tb_sc( ...

  5. Deepin 2014.2正式版发布 - 自由·独特·前卫

    感谢 deepin 的投递 deepin致力于为全球用户提供美观易用.安全可靠的Linux系统. deepin系统使用基于HTML5技术开发的深度桌面环境,搭配深度音乐.深度影院.WPS和搜狗输入法等 ...

  6. JavaScript——Dom编程(1)

    DOM:Document Object Model(文本对象模型) D:文档 – html 文档 或 xml 文档O:对象 – document 对象的属性和方法M:模型 DOM 是针对xml(htm ...

  7. 用JQuery获取输入框中的光标位置

    (function ($, undefined) { $.fn.getCursorPosition = function () { var el = $(this).get(0); var pos = ...

  8. 在Struts2的Action中取得请求参数值的几种方法

    先看GetRequestParameterAction类代码: public class GetRequestParameterAction extends ActionSupport { priva ...

  9. Cookie的跨域问题

    被误解的HttpCookie.Domain属性 有人说可以利用HttpCookie.Domain属性实现跨域访问,假如在A站(A.com)中写B站(B.com)的cookie,如下所示 这其实是错误的 ...

  10. Java 错误结果Throw/Throws

    目录 java处理异常方式    throw的作用    throws的作用    方法原理    举例    总结 个人实例 1.java处理异常方式 在java代码中如果发生异常的话,jvm会抛出 ...