洛谷 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.如果 ...
随机推荐
- Write Once, Run Anywhere:这不是Java,这是C#
注意,本文目的并非挑起语言之争.虽然有为C#平反之意,但主要还是介绍Mono并进行简单的测试. UPDATED: 25th August 2012 更新了「Compile Once, Run Anyw ...
- JS数据结构及算法(一) 堆栈
最近在看<学习JavaScript数据结构与算法>这本书,感觉自己又涨知识了 哈哈... 现在将自己看的做个总结,也是巩固理解. 栈:先进后出,新添加和待删除的元素都保存在栈顶.可以用数组 ...
- Android驱动开发读书笔记五
第五章 本章介绍了S3C6410开发板的功能,开发板的不同主要是在烧录嵌入式系统的方式不同,以及如何在此开发板上安装Android. 1.安装串口调试工具minicom 首先需要一根USB转串口线,由 ...
- Python基础——模块与包
在Python中,可以用import导入需要的模块.包.库.文件等. 把工作路径导入系统路径 import os#os是工作台 import sys#sys是系统 sys.path.append(os ...
- opencv和numpy的安装
近日,学姐让我们切割图片,查了一下资料,发现我需要安装opencv和numpy.但是在安装过程中却出现了很多小问题,我在此结合自和自己的安装经验和网上查找的资料,做一个笔记. 1.opencv的安装 ...
- 请问batch_normalization做了normalization后为什么要变回来?
请问batch_normalization做了normalization后为什么要变回来? 请问batch_normalization做了normalization后为什么要变回来? - 莫驚蟄的回答 ...
- manjaro linux没有ll等命令的解决办法
编辑~/.bashrc, 添加alias 如下 vim ~/.bashrc设置别名. 添加如下行 alias ll='ls -alF' alias la='ls -A' alias vi='vim' ...
- makedown语法
文章转载至:https://blog.csdn.net/u014061630/article/details/81359144#1-%E5%BF%AB%E6%8D%B7%E9%94%AE 前言 写过博 ...
- LeetCode(44) Wildcard Matching
题目 Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single characte ...
- Hard problem CodeForces - 706C
Time limit1000 ms Memory limit262144 kB 题目: Vasiliy is fond of solving different tasks. Today he fou ...