洛谷 P3391 模板Splay
#include<bits/stdc++.h>
using namespace std;
#define maxn 200000
int read()
{
char ch=getchar();int f=,w=;
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch<=''&&ch>=''){w=w*+ch-'';ch=getchar();}
return f*w;
} int n,root,m,tot; struct sj
{
int ch[]; //左儿子和右儿子
int ff,v; //ff是父亲 v
int size; //size是儿子节点个数
int mark; //打上的标记
void init(int x,int fa) //初始化一个节点 左儿子和右儿子以及父亲都清零
{
ff=ch[]=ch[]=;
size=;v=x;ff=fa; //含有子节点个数为1 父亲节点为参数fa
}
}t[maxn]; inline void pushup(int x)
{
t[x].size=t[t[x].ch[]].size+t[t[x].ch[]].size+;
} inline void pushdown(int x)
{
if(t[x].mark)
{
t[t[x].ch[]].mark^=;
t[t[x].ch[]].mark^=;
t[x].mark=;
swap(t[x].ch[],t[x].ch[]);
}
} inline void rotate(int x) //旋转函数
{
int y=t[x].ff;
int z=t[y].ff; //这是爷爷节点
int k=t[y].ch[]==x; //看x是左儿子还是右儿子 k取0,1
t[z].ch[t[z].ch[]==y]=x; //这是把爷爷节点的左/右儿子变成x
t[x].ff=z;
t[y].ch[k]=t[x].ch[k^];
t[t[x].ch[k^]].ff=y;
t[x].ch[k^]=y;
t[y].ff=x; //此段画图理解
pushup(y);pushup(x); //再继续进行修改 push_up();
} inline void splay(int x,int goal)
{
while(t[x].ff!=goal) //当我的这个节点还没有达到目标位置
{
int y=t[x].ff;int z=t[y].ff;
if(z!=goal) //如果还没有跳到目标节点 继续旋转
(t[z].ch[]==y)^(t[y].ch[]==x)?rotate(x):rotate(y); //Warning:: !!!!同边现象时要先翻爸爸再翻儿子 否则不满足搜索树的性质!!!!
rotate(x);
}
if(goal==)root=x; //如果目标节点是0 那么就把root 根节点变成x
} inline void insert(int x)
{
int u=root,ff=; //从根节点开始插入 一开始父亲变成0
while(t[u].size!=)ff=u,u=t[u].ch[x>t[u].v]; //有根的时候 ff父亲变成根节点 u再继续下去向下操作
u=++tot; //tot是实时增加的一个记录子节点个数的全局变量
if(ff)t[ff].ch[x>t[ff].v]=u; //如果父亲不为零 他的父亲的左/右儿子就是u
t[u].init(x,ff); //初始化这个节点 并且它的父亲就是ff
splay(u,); //把这个点旋转到根节点
} inline int get_k(int k)
{
int u=root;
while()
{
pushdown(u);
if(t[t[u].ch[]].size>=k)u=t[u].ch[];
else if(t[t[u].ch[]].size+==k)return u;
else k-=t[t[u].ch[]].size+,u=t[u].ch[];
}
} void write(int u)
{
pushdown(u); //最后输出之前先push_down一遍
if(t[u].ch[])write(t[u].ch[]); //先读左儿子
if(t[u].v>&&t[u].v<n+)printf("%d ",t[u].v-);
if(t[u].ch[])write(t[u].ch[]);
} inline void work(int l,int r) //工作函数
{
l=get_k(l);
r=get_k(r+);
splay(l,);
splay(r,l);
t[t[t[root].ch[]].ch[]].mark^=;
} int main()
{
n=read();m=read(); //n个点 m次翻转
for(int i=;i<=n+;++i)insert(i); //跳过建树 直接插入即可 再继续看insert()
for(int i=;i<=m;i++)
{
int l=read(),r=read();
work(l,r); //工作函数
}
write(root); //输出;
return ; //大工告吉
}
洛谷 P3391 模板Splay的更多相关文章
- 洛谷 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),最后输出结果序列. ...
- 洛谷P3391文艺平衡树(Splay)
题目传送门 转载自https://www.cnblogs.com/yousiki/p/6147455.html,转载请注明出处 经典引文 空间效率:O(n) 时间效率:O(log n)插入.查找.删除 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- BZOJ3223/洛谷P3391 - 文艺平衡树
BZOJ链接 洛谷链接 题意 模板题啦~2 代码 //文艺平衡树 #include <cstdio> #include <algorithm> using namespace ...
- 洛谷P3375 [模板]KMP字符串匹配
To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...
随机推荐
- destoon登录后跳转到指定网址
打开module\member\register.inc.php文件搜索:<input type="hidden" name="forward" valu ...
- js判断是否为app
var ua = navigator.userAgent; var isapp = ua.match("lenovomallapp") == null ? 0 : 1;
- springboot 修改文件上传大小限制
springboot 1.5.9文件上传大小限制spring:http:multipart:maxFileSize:50MbmaxRequestSize:50Mb springboot 2.0文件上传 ...
- 2019.05.26 周日--《阿里巴巴 Java 开发手册》精华摘要
一.写在开头 Java作为一个编程界最流行的语言之一,有着很强的生命力.代码的编写规范也是不容忽视的,今天,我就把自己阅读的国内的互联网巨头阿里巴巴的<阿里巴巴 Java 开发手册>一些精 ...
- Element-ui tree组件自定义节点使用方法
工作上使用到element-ui tree 组件,主要功能是要实现节点拖拽和置顶,通过自定义内容方法(render-content)渲染树代码如下~ <template> <di ...
- C/C++字符串笔试知识点及实例
一.C字符串与C++字符串的深入理解 对于C语言,需要区分C字符串和C字符数组. C字符串:以字符NULL('\0')结尾的字符数组: C字符数组:数组元素类型为字符类型. C字符串的的初始化:c ...
- Windows平台下使用vs code来调试python代码(2)
背景:上篇文章我们介绍了怎么搭建相关的环境,文章链接:https://www.cnblogs.com/yahuian/p/10507467.html,这篇文章来介绍怎么调试我们的程序. 1.Debug ...
- Windows 10 建立wifi热点
如果当前是台式机那么需要一个usb的无线网卡,这里要注意如果你是使用台式机并且通过有线的方式上网,但是你的无线网卡适配器不能在禁用状态. 这里首先打开[运行]输入cmd,打开cmd(注意,这里要使用管 ...
- ubuntu安装easygui模块
使用pip安装easygui 如果未安装pip,则使用如下命令 sudo apt-get install python-pip 安装完pip后,使用如下命令安装easygui sudo pip ins ...
- JAVA基础篇—异常
五种常见异常 1.NullPointerException 空指针 2.ClassNotFoundException 指定类不存在 3.ArithmeticException运算异常 4.ArrayI ...