洛谷 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),最后输出结果序列. ...
随机推荐
- ansible基本使用
ansible介绍 基础概念 ansible是个配置管理工具,可以批量处理一些任务.ansible只需要依赖ssh即可使用,而不需要在受管主机上安装客户端工具. ansible具有幂等性,即以结果为导 ...
- Tornado 类与类组合降低耦合
- 13-爬取百度贴吧中的图片(python+xpath)
通过xpath分析页面,爬取页面中的图片: #_*_ coding: utf-8 _*_ ''' Created on 2018年7月15日 @author: sss function: 使用xpat ...
- c# 获取客户端ip、mac、机器名、操作系统、浏览器信息
d using System; using System.Collections.Generic; using System.Linq; using System.Web; using System. ...
- 性能优化之_android多线程
本文大纲为: 如何创建线程 线程间如何通讯 线程间如何安全的共享信息 一.线程的创建 Thread在run方法中执行具体事务,或者传入一个runnable对象,但是不能调用view控件的更新方法,但是 ...
- PC建立WIFI热点
netsh wlan set hostednetwork ssid=test key =12345678netsh wlan start hostednetwork
- CompositePattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...
- httpd和apache的区别
今天要配置集成服务器环境 apache + tomcat + php + jsp + mysql + sqlserver 去下载apache 发现有: apache_2.2.14-win32-x86 ...
- 防止SQL注入方法总结
一.参数化SQL 是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,用@来表示参数. 在使用参数化查询的情况下,数据库服务器不会将参数的内容视为 ...
- App性能测试工具使用说明-MobilePerformance
一. 环境搭建 安装Android SDK 1.6或者1.7版本均可,建议1.7,环境变量的配置,Java SDK的安装很简单,不赘述了. 安装SDK 1.安装Android SDK: 2.安装完毕后 ...