洛谷 P3391:文艺平衡树 ← Splay树模板题

【题目来源】
https://www.luogu.com.cn/problem/P3391

【题目描述】
您需要写一种数据结构(可参考题目标题),来维护一个有序数列。  其中需要提供以下操作:翻转一个区间,例如原有序序列是 5 4 3 2 1,翻转区间是 [2,4] 的话,结果是 5 2 3 4 1。

【输入格式】
第一行两个正整数 n,m,表示序列长度与操作个数。序列中第 i 项初始为 i。 接下来 m 行,每行两个正整数 l,r,表示翻转的区间。  输出格式 输出一行 n 个正整数,表示原始序列经过 m 次变换后的结果。

【输出格式】
输出一行 n 个正整数,表示原始序列经过 m 次变换后的结果。

【输入样例】
5 3
1 3
1 3
1 4

【输出样例】
​4 3 2 1 5

【数据范围】
对于 100% 的数据,1≤n,m≤100000,1≤l≤r≤n。

【算法分析】
Splay 树简介:https://blog.csdn.net/hnjzsyjyj/article/details/138504578
Treap 树解决平衡的办法是给每个结点加上一个随机的优先级,实现概率上的平衡。Splay 树直接用旋转调整树的形态,通过旋转改善树的平衡性。计算量小,效果好。
● Splay 树的旋转主要分为“
单旋”和“双旋”。
所谓“单旋”,即把结点 x 与它的父结点交换位置,使结点 x 上升一层。“单旋”不会减少树的层数,对改善平衡性没有帮助。根据旋转方向,“单旋”又分为
左旋(zag)右旋(zig)
所谓“双旋”,即两次“单旋”。“双旋”同时旋转
结点 x父结点 f 祖父结点 g 等3个结点,能改善平衡性。“双旋”又分为“一字旋”与“之字旋”。
● Splay 树的旋转示意图

Splay 树的基本操作是把结点旋转到树的根部,这样下次访问它时,只需查一次就 OK 了。
● Splay 树是
动态树(LCT,Link Cut Tree)与树链剖分的基础。
● Splay 树
曾经最常使用的 BST。不过,现在经常使用 FHQ Treap 树实现很多传统的 Splay 树的题目。因为,FHQ Treap 树代码更容易写,效率也很高,且可做持久化

【算法代码】
下面代码是 Splay 树的模板代码,但其中包含了本题(洛谷 P3391)未用的函数。例如:
本例使用了 pushup()、pushdown()、rotate()、splay()、insert()、get_val_by_pri() 、output() 等7个函数;未使用 find()、get_pre()、get_suc()、remove()、get_pri_by_val() 等5个函数。

#include <bits/stdc++.h>
using namespace std;const int maxn=1e5+5;
int n,m;
int root,idx;struct Node {int s[2],v,p; //subtree,val,rootint size,cnt;int lazy;
} tr[maxn];void pushup(int x) {tr[x].size=tr[tr[x].s[0]].size+tr[tr[x].s[1]].size+tr[x].cnt;
}void pushdown(int x) {if(tr[x].lazy) {swap(tr[x].s[0],tr[x].s[1]);tr[tr[x].s[0]].lazy^=1;tr[tr[x].s[1]].lazy^=1;tr[x].lazy=0;}
}void rotate(int x) {int y=tr[x].p;int z=tr[y].p;int k=(tr[y].s[1]==x);tr[z].s[tr[z].s[1]==y]=x, tr[x].p=z;tr[y].s[k]=tr[x].s[k^1], tr[tr[x].s[k^1]].p=y;tr[x].s[k^1]=y, tr[y].p=x;pushup(y), pushup(x);
}void splay(int x,int k) {while(tr[x].p!=k) {int y=tr[x].p;int z=tr[y].p;if(z!=k) {if((tr[y].s[0]==x)^(tr[z].s[0]==y)) rotate(x);else rotate(y);}rotate(x);}if(!k) root=x;
}void insert(int x) {int u=root, p=0;while(u && tr[u].v!=x) {p=u;u=tr[u].s[x>tr[u].v];}if(u) tr[u].cnt++;else {u=++idx;if(p) tr[p].s[x>tr[p].v]=u;tr[u].p=p, tr[u].v=x, tr[u].size=1;tr[u].cnt=1;}splay(u,0);
}void find(int x) {int u=root;while(tr[u].s[x>tr[u].v] && tr[u].v!=x) u=tr[u].s[x>tr[u].v];splay(u,0);
}int get_pre(int x) {find(x);if(tr[root].v<x) return root;int u=tr[root].s[0];while(tr[u].s[1]) u=tr[u].s[1];splay(u,0);return u;
}int get_suc(int x) {find(x);if(tr[root].v>x) return root;int u=tr[root].s[1];while(tr[u].s[0]) u=tr[u].s[0];splay(u,0);return u;
}void remove(int x) {int pre=get_pre(x), suc=get_suc(x);splay(pre,0), splay(suc,pre);int del=tr[suc].s[0];if(tr[del].cnt>1) tr[del].cnt--, splay(del,0);else tr[suc].s[0]=0, splay(suc,0);
}int get_pri_by_val(int x) {insert(x);int ans=tr[tr[root].s[0]].size;remove(x);return ans;
}int get_val_by_pri(int x) {int u=root;while(true) {pushdown(u);if(x<=tr[tr[u].s[0]].size) u=tr[u].s[0];else if(x==tr[tr[u].s[0]].size+1) return u;else x-=tr[tr[u].s[0]].size+1, u=tr[u].s[1];}return -1;
}void output(int x) {pushdown(x);if(tr[x].s[0]) output(tr[x].s[0]);if(1<=tr[x].v && tr[x].v<=n) printf("%d ",tr[x].v);if(tr[x].s[1]) output(tr[x].s[1]);
}int main() {scanf("%d %d",&n,&m);for(int i=0; i<=n+1; i++) insert(i);while(m--) {int le,ri;scanf("%d%d",&le,&ri);le=get_val_by_pri(le);ri=get_val_by_pri(ri+2);splay(le,0);splay(ri,le);tr[tr[ri].s[0]].lazy^=1;}output(root); //inorderreturn 0;
}/*
in:
5 3
1 3
1 3
1 4out:
4 3 2 1 5
*/




【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/138504578
https://www.acwing.com/file_system/file/content/whole/index/content/6921304/
https://www.acwing.com/file_system/file/content/whole/index/content/6420964/



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/833893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习常用优化算法笔记介绍,各种梯度下降法详细介绍

优化算法 mini-batch梯度下降法 当一个数据集其数据量非常大的时候&#xff0c;比如上百万上千万的数据集&#xff0c;如果采用普通的梯度下降法&#xff0c;那么运算速度会非常慢&#xff0c;因为如果使用梯度下降法在每一次迭代的时候&#xff0c;都需要将这整个上百万的数…

航空电子FC节点卡, FC交换机,主要采用LC或MPO光纤接口形式

FC节点卡主要采用LC或MPO光纤接口形式&#xff0c;可以作为4/2个独立端口使用&#xff0c;也可以作为2对/1对冗余端口使用&#xff0c;支持1.0625Gbps、2.125Gbps、4.25Gbps、8.5Gbps通信速率。节点卡完全遵循FC-LS&#xff0c;FC-FS&#xff0c;FC-AE-ASM、FC-AE-1553B等FC光纤…

初始Java篇(JavaSE基础语法)(7)抽象类和接口(上)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaSE 目录 抽象类 抽象类的概念&#xff1a; 抽象类语法 抽象类特性 抽象类的作用 接口 接口的概念&#xff1a; 语法规则 接口…

精通GDBus:Linux IPC的现代C接口

目录标题 1. GDBus介绍2. GDBus的优点3. 安装GDBus4. 使用GDBus连接到D-Bus总线实现D-Bus服务调用D-Bus方法发送和接收信号 5. 总结 在Linux环境下&#xff0c;不同的程序需要通过某种方式进行通信和协同工作。GDBus是GLib库的一部分&#xff0c;提供了一个基于GObject系统的、…

单片机-点亮第一盏灯

原理图 需求&#xff1a;点亮或是熄灭LED 通过控制 P5.3引脚输出高电平时&#xff0c;LED灯就点亮&#xff0c;输出低电平时LED灯就熄灭 1.项目创建 新建项目 配置开发板信息 当前位STC芯片的开发板&#xff0c;选择STC MCU Database 搜素具体芯片型号&#xff0c;进行配置…

[MySQL数据库] Java的JDBC编程(MySQL数据库基础操作完结)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

【北京迅为】《iTOP-3588开发板快速烧写手册》-第8章 TF启动

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

C/C++ 初级球球大作战练手

效果演示&#xff1a; https://live.csdn.net/v/385490 游戏初始化 #include <stdbool.h> #include<stdio.h> #include<stdlib.h> #include<time.h> #include<graphics.h> #include <algorithm> #include<math.h> #include<mmsy…

java多线程编码应用1——java多线程CompletableFuture使用技巧

在实际项目开发过程中&#xff0c;大部分程序的执行顺序都是按照代码编写的先后顺序&#xff0c;依次从上往下挨个执行的&#xff0c;但是对于统计或者批量操作数据时&#xff0c;是否有更好的方案呢&#xff1f;这时候就可以考虑使用多线程编程&#xff0c;异步并行执行多个任…

【MATLAB画图】如何绘制图像坐标系

首先我们需要图像坐标轴的原点在左上角&#xff1a; set(gca,ydir,reverse,xaxislocation,top); 然后我们需要坐标轴上加上箭头 quiver(0, 0, 0, 520); % 在(x1, y1)处绘制一个箭头&#xff0c;其方向和长度由(dx, dy)确定 quiver(0, 0, 700, 0); % 在(x1, y1)处绘制一个箭头…

英语新概念2-回译法-lesson13

The Greenwood Boys 绿林少年是一组流行歌手们。现在他们正在参观城市里的所有公园&#xff0c;他们明天就要到这。他们将坐火车到并且大多数小镇上的年轻人将要欢迎他们&#xff0c;明天晚上他们将要在工人俱乐部唱歌。绿林少年将在这待五天&#xff0c;在这期间&#xff0c;…

flowable一对并发网关跳转的分析

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

前端面试题大合集3----网络篇

目录 一、Http协议详解&#xff0c;http请求方式&#xff0c;http状态码 Http协议详解&#xff1a; http请求方式&#xff1a; http状态码&#xff1a; 常用的状态码&#xff1a; 其他常用状态码&#xff1a; 二、Http常见请求方式 三、Http协议与TCP协议的区别和联系 …

【STM32G474】利用Cpp编写STM32代码后,Cubemx修改配置后代码报错147个error,如何处理?

问题描述 打开Cubemx&#xff0c;添加TIM7用于定时器精准延时&#xff0c;生成代码后&#xff0c;Keil提示有147个error。 之前是Cubemx是没有问题的&#xff0c;是利用Cpp编写stm32&#xff08;将Keil改为Version6&#xff09;后才导致Cubemx配置失败&#xff1a; debug成功…

Mybatis进阶2

Mybatis进阶1-CSDN博客 Mybatis入门-CSDN博客 Mybatis入门2-CSDN博客 我们接下来要学习Mybatis的高级查询 我们先在数据库中准备我们需要的数据表 teacher表 课程表&#xff1a;与教师表是一对多的关系&#xff0c;所以有一个外键字段 学生表 由于学生表和课程表是多对多的…

《Python编程从入门到实践》day22

# 昨日知识点回顾 方法重构、驾驶飞船左右移动、全屏显示 飞船不移动解决&#xff0c;问题出在移动变量x更新 # Ship.pysnipdef update(self):"""根据移动标志调整飞船的位置"""# 更新飞船而不是rect对象的x值# 如果飞船右移的标志和飞船外接…

射频无源器件之电桥

一. 电桥的定义及作用 电桥主要用于实现微波大功率功放系统的功率合成分配,信号采集等功能,被广泛应用于中国及全球4G/5G基站、5G网络覆盖、北斗导航天线、车载高精度导航(无人驾驶)天线等。可将信号分成有相位差的两路,90度电桥相位差90,180度电桥相位差180。 常说的3d…

Redis学习2——SpringBoot整合Redis,Redis工具类

依赖和配置 pom.xml SpringBoot整合Redis&#xff0c;需要引入spring-boot-starter-data-redis依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>当…

stm32_RTC_2_HAL——stm32CudeMX

介绍 RTC&#xff08;实时时钟&#xff09;不仅仅提供计数功能&#xff0c;它是一个完整的时钟和日历模块&#xff0c;用于提供日期和时间信息。RTC 能够提供年、月、日、星期、时、分、秒等时间信息&#xff0c;并且通常具有闹钟功能&#xff0c;可以用于定时唤醒或触发事件。…

C++学习第十二天(继承)

1、继承的概念以及定义 继承的概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行拓展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层次结构&#x…