Description

H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构。伸展树(splay)是一种数据
结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必修技能。有一天,邪恶的“卡”带着
他的邪恶的“常数”来企图毁灭 H 国。“卡”给 H 国的人洗脑说,splay 如果写成单旋的,将会更快。“卡”称
“单旋 splay”为“spaly”。虽说他说的很没道理,但还是有 H 国的人相信了,小 H 就是其中之一,spaly 马
上成为他的信仰。 而 H 国的国王,自然不允许这样的风气蔓延,国王构造了一组数据,数据由 m 个操作构成,
他知道这样的数据肯定打垮 spaly,但是国王还有很多很多其他的事情要做,所以统计每个操作所需要的实际代价
的任务就交给你啦。
 
数据中的操作分为五种:
 
1. 插入操作:向当前非空 spaly 中插入一个关键码为 key 的新孤立节点。插入方法为,先让 key 和根比较,如果 
key 比根小,则往左子树走,否则往右子树走,如此反复,直到某个时刻,key 比当前子树根 x 小,而 x 的左子
树为空,那就让 key 成为 x 的左孩子; 或者 key 比当前子树根 x 大,而 x 的右子树为空,那就让 key 成为 
x 的右孩子。该操作的代价为:插入后,key 的深度。特别地,若树为空,则直接让新节点成为一个单个节点的树
。(各节点关键码互不相等。对于“深度”的解释见末尾对 spaly 的描述)。
2. 单旋最小值:将 spaly 中关键码最小的元素 xmin 单旋到根。操作代价为:单旋前 xmin 的深度。
(对于单旋操作的解释见末尾对 spaly 的描述)。
3. 单旋最大值:将 spaly 中关键码最大的元素 xmax 单旋到根。操作代价为:单旋前 xmax 的深度。
4. 单旋删除最小值:先执行 2 号操作,然后把根删除。由于 2 号操作之后,根没有左子树,所以直接切断根和右子
树的联系即可(具体见样例解释)。 操作代价同 2 号操 作。
5. 单旋删除最大值:先执行 3 号操作,然后把根删除。 操作代价同 3 号操作。
 
对于不是 H 国的人,你可能需要了解一些 spaly 的知识,才能完成国王的任务:
 
a. spaly 是一棵二叉树,满足对于任意一个节点 x,它如果有左孩子 lx,那么 lx 的关键码小于 x 的关键码。
如果有右孩子 rx,那么 rx 的关键码大于 x 的关键码。
b. 一个节点在 spaly 的深度定义为:从根节点到该节点的路径上一共有多少个节点(包括自己)。
c. 单旋操作是对于一棵树上的节点 x 来说的。一开始,设 f 为 x 在树上的父亲。如果 x 为 f 的左孩子,那么
执行 zig(x) 操作(如上图中,左边的树经过 zig(x) 变为了右边的树),否则执行 zag(x) 操作(在上图中,将
右边的树经过 zag(f) 就变成了左边的树)。每当执 行一次 zig(x) 或者 zag(x),x 的深度减小 1,如此反复,
直到 x 为根。总之,单旋 x 就是通过反复执行 zig 和 zag 将 x 变为根。

Input

第一行单独一个正整数 m。
接下来 m 行,每行描述一个操作:首先是一个操作编号 c∈[1,5],即问题描述中给出的五种操作中的编号,若 c
 = 1,则再输入一个非负整数 key,表示新插入节点的关键码。
1≤m≤10^5,1≤key≤10^9
所有出现的关键码互不相同。任何一个非插入操作,一定保证树非空。在未执行任何操作之前,树为空

Output

输出共 m 行,每行一个整数,第 i 行对应第 i 个输入的操作的代价。
用set维护一下当前在树上的点以便快速插入新点,lct维护树的形态支持询问点的深度,每个操作只需$O(1)$次link/cut/查询深度,时间复杂度$O(nlogn)$
#include<cstdio>
#include<set>
const int N=1e5+;
namespace lct{
#define lc ch][0
#define rc ch][1
#define fa ch][2
#define sz ch][3
int ch[N][];
bool nrt(int x){
return x==x[fa][lc]||x==x[fa][rc];
}
void up(int x){
x[sz]=+x[lc][sz]+x[rc][sz];
}
void rot(int x){
int f=x[fa],g=f[fa],d=x==f[rc];
if(nrt(f))g[ch][g[rc]==f]=x;
x[fa]=g;
(f[ch][d]=x[ch][d^])[fa]=f;
(x[ch][d^]=f)[fa]=x;
up(f);up(x);
}
void sp(int x){
while(nrt(x)){
int f=x[fa];
if(nrt(f))rot((x==f[lc])==(f==f[fa][lc])?f:x);
rot(x);
}
}
void acs(int x){
for(int y=;x;sp(x),x[rc]=y,up(x),y=x,x=x[fa]);
}
void ct(int x){
acs(x);sp(x);
x[lc][fa]=;
x[lc]=;
up(x);
}
void lk(int x,int y){
sp(x);
x[fa]=y;
}
void query(int x){
acs(x);
sp(x);
printf("%d\n",x[lc][sz]+);
}
#undef lc
#undef rc
#undef fa
#undef sz
}
#define G *++ptr
char buf[N*],*ptr=buf-;
int q,o,x,rt=,ch[N][],fa[N],p=;
int _(){
int x=,c=G;
while(c<)c=G;
while(c>)x=x*+c-,c=G;
return x;
}
struct pos{
int x,y;
bool operator<(pos w)const{return x<w.x;}
};
std::set<pos>st;
void setc(int w,int d,int u){
fa[ch[w][d]=u]=w;
lct::lk(u,w);
}
void setc(int w,int d){
int u=ch[w][d];
fa[u]=ch[w][d]=;
lct::ct(u);
}
void ins(int x){
int u=++p;
lct::ch[u][]=;
if(!rt){
rt=u;
}else{
std::set<pos>::iterator it=st.upper_bound((pos){x,});
if(it==st.end()||ch[it->y][]){
--it;
setc(it->y,,u);
}else{
setc(it->y,,u);
}
}
lct::query(u);
st.insert((pos){x,u});
}
int main(){
fread(buf,,sizeof(buf),stdin)[buf]=;
for(q=_();q;--q){
o=_();
if(o==){
x=_();
ins(x);
}else if(o==||o==){
int w=st.begin()->y,c=ch[w][],f=fa[w];
lct::query(w);
if(f){
setc(f,);
if(c)setc(w,),setc(f,,c);
if(o==)setc(w,,rt),rt=w;
}else if(o==){
if(c)setc(w,),rt=c;
}
if(o==)st.erase(st.begin());
}else if(o==||o==){
int w=(--st.end())->y,c=ch[w][],f=fa[w];
lct::query(w);
if(f){
setc(f,);
if(c)setc(w,),setc(f,,c);
if(o==)setc(w,,rt),rt=w;
}else if(o==){
if(c)setc(w,),rt=c;
}
if(o==)st.erase(--st.end());
}
if(st.empty())rt=;
}
return ;
}

bzo j4825 [Hnoi2017]单旋的更多相关文章

  1. bzoj 4825: [Hnoi2017]单旋 [lct]

    4825: [Hnoi2017]单旋 题意:有趣的spaly hnoi2017刚出来我就去做,当时这题作死用了ett,调了5节课没做出来然后发现好像直接用lct就行了然后弃掉了... md用lct不知 ...

  2. 【LG3721】[HNOI2017]单旋

    [LG3721][HNOI2017]单旋 题面 洛谷 题解 20pts 直接模拟\(spaly\)的过程即可. 100pts 可以发现单旋最大.最小值到根,手玩是有显然规律的,发现只需要几次\(lin ...

  3. 4825: [Hnoi2017]单旋

    4825: [Hnoi2017]单旋 链接 分析: 以后采取更保险的方式写代码!!!81行本来以为不特判也可以,然后就总是比答案大1,甚至出现负数,调啊调啊调啊调~~~ 只会旋转最大值和最小值,以最小 ...

  4. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 667  Solved: 342[Submit][Status][ ...

  5. 【BZOJ4825】[Hnoi2017]单旋 线段树+set

    [BZOJ4825][Hnoi2017]单旋 Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能 ...

  6. bzoj4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  7. BZOJ:4825: [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  8. HNOI2017 单旋

    题目描述 网址:https://www.luogu.org/problemnew/show/3721 大意: 有一颗单旋Splay(Spaly),以key值为优先度,总共有5个操作. [1] 插入一个 ...

  9. HNOI2017单旋

    单旋 这道题做法贼多,LCT,splay,线段树什么的貌似都行. 像我这种渣渣只会线段树了(高级数据结构学了也不会用). 首先离线所有操作,因为不会有两个点值重复,所以直接离散. 一颗线段树来维护所有 ...

随机推荐

  1. CentOS7.2 安装RabbitMQ3.6.10

    CentOS上面使用yum安装比较方便 先记录一些rabbitmq的基本操作命令: $ sudo chkconfig rabbitmq-server on # 添加开机启动RabbitMQ服务 $ s ...

  2. 视觉SLAM漫谈 (三): 研究点介绍

    1. 前言 读者朋友们大家好!(很久很久)之前,我们为大家介绍了SLAM的基本概念和方法.相信大家对SLAM,应该有了基本的认识.在忙完一堆写论文.博士开题的事情之后,我准备回来继续填坑:为大家介绍S ...

  3. 【eclipse】svn在线安装

    Subclipse1.8 http://subclipse.tigris.org/update_1.8.x

  4. python 去除不可见的控制字符

    尤其是在json load的时候,字符串中的不可见控制字符可能会导致错误,应该先对字符串进行控制字符过滤. 对网页文本同样适用,最好在处理网页文本时先进性控制字符清洗. Replace null by ...

  5. HTML 入门1

    HTML   入门1  一,什么是HTML 超文本标记语言 二,如何写一个HTML文件? 1 通过sublime的文件->新建->保存 "文件名.html"格式 2,在 ...

  6. GetLastError()数字_转换为_文字

    1.具体参数 可参看 http://blog.csdn.net/hongweigg/article/details/6821536 或 其它文章 或 MSDN 2.VC6 测试代码: #include ...

  7. js 杂谈

    js解释器有自己的内存管理机制(垃圾回收:自动回收无引用指向对象) js采用一种数字类型(64位浮点数),100与1e2完全相等 条件判断是被当为假的值:false.null.undefined.‘’ ...

  8. PythonInstaller编译EXE方法+编译过程出错方案大全

    https://www.cnblogs.com/gopythoner/p/6337543.htmlhttps://www.zhihu.com/question/22963200https://blog ...

  9. 2243: [SDOI2011]染色 树链剖分+线段树染色

    给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...

  10. UVA-307 Sticks (DFS+剪枝)

    题目大意:用n根长度未必相等的木棒匹配出最多数量的等长木棒. 题目分析:枚举所有可能的等长木棒的长度,通过DFS的方式逐根匹配,在此过程中要剪枝.先将木棒长度按从大到小排序,也就是说匹配每一根等长木棒 ...