洛谷 P3391【模板】文艺平衡树(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
说明
\(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)的更多相关文章
- 洛谷.3391.[模板]文艺平衡树(Splay)
题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...
- 【洛谷P3391】文艺平衡树——Splay学习笔记(二)
题目链接 Splay基础操作 \(Splay\)上的区间翻转 首先,这里的\(Splay\)维护的是一个序列的顺序,每个结点即为序列中的一个数,序列的顺序即为\(Splay\)的中序遍历 那么如何实现 ...
- 洛谷.3369.[模板]普通平衡树(Splay)
题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- 洛谷 P3391 模板Splay
#include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...
- 【洛谷P3369】普通平衡树——Splay学习笔记(一)
二叉搜索树(二叉排序树) 概念:一棵树,若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉搜索树 ...
- 洛谷.3369.[模板]普通平衡树(fhq Treap)
题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...
- 洛谷 P3391 【模板】文艺平衡树(Splay)
题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1, ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- [洛谷P3391] 文艺平衡树 (Splay模板)
初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...
随机推荐
- 让IE10等支持classList2.0
chrome24+, firesfox26+起支持classList2.0,即让它同时添加或删除多个类名, toggle方法支持第2个参数,用于强制添加或删除 var div = document.c ...
- apk安装包信息
String archiveFilePath="sdcard/DangDang.apk";//安装包路径 PackageManager pm = getPacka ...
- powerdesigner设计的pdm模型导出清晰图片格式
用powerdesigner设计了数据库模型,想把模型粘贴到数据库文档中,之前一直是Ctrl+A然后复制,直接粘贴过去的,这次领导说放大看不清,o(╯□╰)o 没办法,得搞个高清图复制上去啊,怎么办呢 ...
- ubuntu 下正确安装android手机驱动
1. 查看手机ID号. charlesxue@THSHIBA:~/setup/cocos2d-x/cocos2d-x-/projects/simpleGame/proj.android/bin$ ls ...
- web 应用中访问 Spring 具体实现
user=LF password=LF jdbcUrl=jdbc:oracle:thin:@localhost:1521:orcl driverClass=oracle.jdbc.driver.Ora ...
- 11-内涵段子-爬虫(python+正则)
爬取内涵段子,使用正则进行简单处理: #_*_ coding: utf-8 _*_ ''' Created on 2018年7月14日 @author: sss function:爬去内涵段子(静态网 ...
- csv、txt读写及模式介绍
1读写模式 r以读方式打开文件,可读取文件信息 w已写方式打开文件,可向文件写入信息.如文件存在,则清空,再写入 a以追加模式打开文件,打开文件可指针移至末尾,文件不存在则创建 r+以读写方式打开文件 ...
- Vue.js组件调用用及其组件通信
1.需要import,然后components注册.然后如下代码调用. <template> <header></header> //注册后才能这样使用 <b ...
- php系统常量
(1)__FILE__ :php程序文件名.它可以帮助我们获取当前文件在服务器的物理位置. (2)__LINE__ :PHP程序文件行数.它可以告诉我们,当前代码在第几行. (3)PHP_VERSIO ...
- MySQL事务隔离级别测试实例
https://www.cnblogs.com/huanongying/p/7021555.html MySQL事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommit ...