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 n1≤l≤r≤n

输出格式:

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

输入输出样例

输入样例#1: 复制

5 3
1 3
1 3
1 4
输出样例#1: 复制

4 3 2 1 5

说明

code

 #include<cstdio>
#include<algorithm> using namespace std; const int N = ;
int ch[N][],tag[N],val[N],siz[N],key[N];
int tn,Root,n,m; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF : *p1++;
}
inline int read() {
int x = ,f = ;char ch = nc();
for (; ch<''||ch>''; ch = nc())
if (ch=='-') f = -;
for (; ch>=''&&ch<=''; ch = nc())
x = x*+ch-'';
return x * f;
}
inline void pushup(int x) {
siz[x] = siz[ch[x][]] + siz[ch[x][]] + ;
}
inline void pushdown(int x) {
if (tag[x]) {
tag[ch[x][]] ^= ;tag[ch[x][]] ^= ;
swap(ch[x][],ch[x][]);
tag[x] ^= ;
}
}
inline int makenode(int x) {
++tn;siz[tn] = ;val[tn] = x;key[tn] = rand();return tn;
}
int merge(int x,int y) {
if (!x || !y) return x + y;
pushdown(x);pushdown(y);
if (key[x] < key[y]) {
ch[x][] = merge(ch[x][],y);
pushup(x);return x;
}
else {
ch[y][] = merge(x,ch[y][]);
pushup(y);return y;
}
}
void split(int now,int k,int &x,int &y) {
if (!now) x = y = ;
else {
pushdown(now);
if (k<=siz[ch[now][]])
y = now,split(ch[now][],k,x,ch[now][]);
else
x = now,split(ch[now][],k-siz[ch[now][]]-,ch[now][],y);
pushup(now);
}
}
inline void rever(int l,int r) {
int a,b,c,d;
split(Root,r,a,b);
split(a,l-,c,d);
tag[d] ^= ;
Root = merge(merge(c,d),b);
}
void print(int x) {
if (!x) return ;
pushdown(x);
print(ch[x][]);
printf("%d ",val[x]);
print(ch[x][]);
}
int main() {
n = read(),m = read();
for (int i=; i<=n; ++i) {
Root = merge(Root,makenode(i));
}
while (m--) {
int a = read(),b = read();
rever(a,b);
}
print(Root);
return ;
}

网上学的另一种建树方法:

 int build(int l,int r)
{
if (l>r) return ;
int mid=(l+r)>>,v=mid;
int now=makenode(v);
ch[now][]=build(l,mid-);
ch[now][]=build(mid+,r);
pushup(now);
return now;
}
Root = build(,n);

虽然可能不满足堆的性质,但是,堆在这个过程中只是调节树的平衡的,所以还是可以过的

板子的发展史。。。

 #include<cstdio>
#include<algorithm> using namespace std; const int N = ;
int ch[N][],tag[N],val[N],siz[N],key[N];
int tn,Root,n,m; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF : *p1++;
}
inline int read() {
int x = ,f = ;char ch = nc();
for (; ch<''||ch>''; ch = nc())
if (ch=='-') f = -;
for (; ch>=''&&ch<=''; ch = nc())
x = x*+ch-'';
return x * f;
}
inline void pushup(int x) {
siz[x] = siz[ch[x][]] + siz[ch[x][]] + ;
}
inline void pushdown(int x) {
if (tag[x]) {
tag[ch[x][]] ^= ;tag[ch[x][]] ^= ;
swap(ch[x][],ch[x][]);
tag[x] ^= ;
}
}
inline int makenode(int x) {
++tn;siz[tn] = ;val[tn] = x;key[tn] = rand();return tn;
}
int merge(int x,int y) {
if (!x || !y) return x + y;
if (key[x] < key[y]) {
pushdown(x);
ch[x][] = merge(ch[x][],y);
pushup(x);return x;
}
else {
pushdown(y);
ch[y][] = merge(x,ch[y][]);
pushup(y);return y;
}
}
void split(int now,int k,int &x,int &y) {
if (!now) x = y = ;
else {
pushdown(now);
if (k<=siz[ch[now][]])
y = now,split(ch[now][],k,x,ch[now][]);
else
x = now,split(ch[now][],k-siz[ch[now][]]-,ch[now][],y);
pushup(now);
}
}
inline void rever(int l,int r) {
int a,b,c,d;
split(Root,r,a,b);
split(a,l-,c,d);
tag[d] ^= ;
Root = merge(merge(c,d),b);
}
void print(int x) {
if (!x) return ;
pushdown(x);
print(ch[x][]);
printf("%d ",val[x]);
print(ch[x][]);
}
int main() {
n = read(),m = read();
for (int i=; i<=n; ++i) {
Root = merge(Root,makenode(i));
}
while (m--) {
int a = read(),b = read();
rever(a,b);
}
print(Root);
return ;
}

P3391 【模板】文艺平衡树FHQ treap的更多相关文章

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

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

  2. 2021.12.08 平衡树——FHQ Treap

    2021.12.08 平衡树--FHQ Treap http://www.yhzq-blog.cc/fhqtreapzongjie/ https://www.cnblogs.com/zwfymqz/p ...

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

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

  4. Luogu P3835 【模板】可持久化平衡树(fhq Treap)

    P3835 [模板]可持久化平衡树 题意 题目背景 本题为题目普通平衡树的可持久化加强版. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作(对于各个以往的历史版本 ...

  5. 洛谷.3835.[模板]可持久化平衡树(fhq treap)

    题目链接 对每次Merge(),Split()时产生的节点都复制一份(其实和主席树一样).时间空间复杂度都为O(qlogq).(应该更大些 因为rand()?内存真的爆炸..) 对于无修改的操作实际上 ...

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

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

  7. 洛谷.3391.文艺平衡树(fhq Traep)

    题目链接 //注意反转时先分裂r,因为l,r是针对整棵树的排名 #include<cstdio> #include<cctype> #include<algorithm& ...

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

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

  9. FHQ Treap及其可持久化与朝鲜树式重构

    FHQ Treap,又称无旋treap,一种不基于旋转机制的平衡树,可支持所有有旋treap.splay等能支持的操作(只有在LCT中会比splay复杂度多一个log).最重要的是,它是OI中唯一一种 ...

随机推荐

  1. 报错:Could not reserve enough space for object heap error

    windows命令行运行某个命令时出现: 解决办法: 设置开始->控制面板->系统和安全->系统->高级系统设置->环境变量->系统变量->新建: 变量名: ...

  2. JS的使用

    Javascript代码在浏览器中运行,做出更流畅.优美的页面效果,增强用户体验与java是完全不同的东西,只是名称类似而已写在<script></script>标签中 大小写 ...

  3. GDI绘制图形的使用_验证码

    //创建GDI对象 Graphics g = this.CreateGraphics();// new Graphics(); //创建画笔对象 Pen pen = new Pen(Brushes.R ...

  4. JavaBean+jsp开发模式 --结合form表单 实例

    1.创建form表单 <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...

  5. LoadRunner创建脚本和场景流程

    1)脚本创建流程创建脚本->选择协议-设置录制选项-录制脚本-停止录制-优化脚本(去掉无用内容)-强化脚本(注释.代码结构调整.参数化.检查点.事物.关联)-调试脚本(观察日志) 2)场景设置的 ...

  6. LoadRunner使用(1)

    一.LoadRunner脚本录制 LoadRunner测试分为两个步骤: 第一步:录制脚本,其实就是监控并记录这段时间发送的HTTP请求 第二步:启动多个线程,用录制的脚本,模拟多线程发送请求. (1 ...

  7. Java-Web总结03

    *1 dom4j解析器   1)CRUD的含义:CreateReadUpdateDelete增删查改   2)XML解析器有二类,分别是DOM和SAX. a)DOM一次性将整个XML文件读到内存,形成 ...

  8. OpenGL小试牛刀第一季

    效果截图:代码展示:using System;using System.Collections.Generic;using System.ComponentModel;using System.Dat ...

  9. python 产生随机数

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

  10. 03_10_Object类的toString equals等方法

    03_10_Object类的toString equals等方法 1. toString方法 Object类中定义有public String toString()方法,其返回值是String类型,描 ...