题目大意

spaly是一种数据结构,它是只有单旋的splay

有一个初始为空的spaly,\(m\)(\(m\leq10^5\))次操作,每个操作是以下5种中的一种:

1.向spaly中插入一个数(过程和treap的插入类似,只不过插入之后不会调整),并询问这个数的深度

2.询问最小值的深度,并将它splay到根

3.询问最大值的深度,并将它splay到根

4.询问最小值的深度,将它splay到根并把它删掉

5.询问最大值的深度,将它splay到根并把它删掉

题解

直接维护spaly的话,spaly不一定平衡,“从一个根走到一个点”和“把一个点旋转到根”的复杂度会很大

对于1操作,发现新插入的数的父亲一定是它的前驱或者后继中深度更大的那个,直接把它接过去,并把它的深度置为父亲的深度+1就行

对于2,3,4,5操作,发现被splay的点只可能是最小或最大的点

在把最小值或最大值转到根时,会发现只要把它的儿子接到它的父亲、把原来的根接到它就可以

在这个过程中,要把它子树外的点深度+1,如果还要删掉它的话就把所有点深度-1

用splay维护前驱后继、最大值最小值、区间加单点查询

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>0
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 100010
#define inf 2147483647
#define ls son[u][0]
#define rs son[u][1]
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
int dep[maxn],son[maxn][2],fa[maxn],key[maxn],mk[maxn],rt;
int fakefa[maxn],fakeson[maxn][2],fakert,n,cnt;
void mark(int u,int k){if(u)dep[u]+=k,mk[u]+=k;}
void pd(int u){if(mk[u]&&u)mark(ls,mk[u]),mark(rs,mk[u]),mk[u]=0;}
int getso(int u){return son[fa[u]][0]!=u;}
int newnd(int k,int f){int u=++cnt;ls=rs=0,key[u]=k,fa[u]=f;return u;}
void rot(int u)
{
int fu=fa[u],ffu=fa[fu],l=getso(u),fl=getso(fu),r=l^1,rson=son[u][r];
fa[rson]=fu,fa[u]=ffu,fa[fu]=u,son[u][r]=fu,son[fu][l]=rson,son[ffu][fl]=u;
}
void splay(int u,int k)
{
pd(u);while(fa[u]!=k){if(mk[fa[u]])cout<<"nooo"<<endl;if(fa[fa[u]]!=k)rot(getso(u)^getso(fa[u])?u:fa[u]);rot(u);}
if(!k)rt=u;
}
void fnd(int k)
{
int u=rt;
while(key[u]!=k&&son[u][key[u]<k])pd(u),u=son[u][key[u]<k];
splay(u,0);
}
int nxt(int k,int f)
{
fnd(k);int u=rt;
if((key[u]<k&&!f)||(key[u]>k&&f))return u;
pd(u),u=son[u][f];
while(u&&son[u][f^1])pd(u),u=son[u][f^1];
return u;
}
void ins(int k)
{
int lk=nxt(k,0),rk=nxt(k,1),mxk=dep[lk]>dep[rk]?lk:rk;
splay(lk,0),splay(rk,lk);
son[rk][0]=newnd(k,rk),dep[cnt]=dep[mxk]+1;
if(mxk<=2)fakert=cnt;
else fakeson[mxk][key[mxk]<k?1:0]=cnt,fakefa[cnt]=mxk;
}
void del(int k)
{
int lk=nxt(k,0),rk=nxt(k,1);
splay(lk,0),splay(rk,lk);
son[rk][0]=0;
}
void add(int l,int r,int k)
{
int lk=nxt(l,0),rk=nxt(r,1);
//cout<<"adl:"<<l<<" adr:"<<r<<" adk:"<<k<<endl;
splay(lk,0),splay(rk,lk),mark(son[rk][0],k);
}
int spaly(int u,int f)
{
int res;
res=dep[u],dep[u]=1,add(f?-inf+1:key[fakefa[u]],f?key[fakefa[u]]:inf-1,1);
fakeson[fakefa[u]][f]=fakeson[u][f^1],fakefa[fakeson[u][f^1]]=fakefa[u];
fakefa[fakert]=u,fakeson[u][f^1]=fakert,fakert=u;
return res;
}
int main()
{
rt=newnd(inf,0),son[rt][0]=newnd(-inf,rt);
n=read();
while(n--)
{
int f=read();
if(f==1)
{
int k=read();ins(k);
write(dep[cnt]);
}
else if(f==2)
{
int ans=0,u=nxt(-inf,1);
if(fakert!=u)ans=spaly(u,0);
else ans=1;
write(ans);
}
else if(f==3)
{
int ans=0,u=nxt(inf,0);
if(fakert!=u)ans=spaly(u,1);
else ans=1;
write(ans);
}
else if(f==4)
{
int ans=0,u=nxt(-inf,1);
if(fakert!=u)ans=spaly(u,0);
else ans=1;
write(ans);
fakert=fakeson[u][1],fakefa[fakert]=0,del(key[u]),add(-inf+1,inf-1,-1);
}
else if(f==5)
{
int ans=0,u=nxt(inf,0);
if(fakert!=u)ans=spaly(u,1);
else ans=1;
write(ans);
fakert=fakeson[u][0],fakefa[fakert]=0,del(key[u]),add(-inf+1,inf-1,-1);
}
}
return 0;
}

并不对劲的bzoj4825:loj2018:p3721:[HNOI2017]单旋的更多相关文章

  1. [bzoj4825] [loj#2018] [Hnoi2017] 单旋

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

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

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

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

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

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

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

  5. 【LG3721】[HNOI2017]单旋

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

  6. 4825: [Hnoi2017]单旋

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

  7. P3721 [AH2017/HNOI2017]单旋

    题目:https://www.luogu.org/problemnew/show/P3721 手玩一下即可AC此题. 结论:插入x后,x要么会成为x的前驱的右儿子,要么成为x的后继的左儿子,这取决于它 ...

  8. bzoj4825 [Hnoi2017]单旋

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

  9. BZOJ4825: [Hnoi2017]单旋(Splay)

    题面 传送门 题解 调了好几个小时--指针太难写了-- 因为只单旋最值,我们以单旋\(\min\)为例,那么\(\min\)是没有左子树的,而它旋到根之后,它的深度变为\(1\),它的右子树里所有节点 ...

随机推荐

  1. 64.JPA命名策略【从零开始学Spring Boot】

    [从零开始学习Spirng Boot-常见异常汇总] 在(39.2). Spring Boot Shiro权限管理[从零开始学Spring Boot] 这一章节中有人碰到这样一个问题"导入的 ...

  2. Go函数学习

    package main import ( "fmt" "reflect" "runtime" "math" ) //函 ...

  3. POJ 1509 循环同构的最小表示法

    题目大意: 给定一个字符串,可以把一段尾部接到头部,这样找到一个最小的字符串 方案一: 利用循环同构中找最小表示的方法来解决 论文参考http://wenku.baidu.com/view/438ca ...

  4. SpringBoot 配置 @PropertySource、@ImportResource、@Bean

    一.@PropertySource @PropertySource:加载指定的配置文件 @PropertySource(value = {"classpath:person.properti ...

  5. poj1330+hdu2586 LCA离线算法

    整整花了一天学习了LCA,tarjan的离线算法,就切了2个题. 第一题,给一棵树,一次查询,求LCA.2DFS+并查集,利用深度优先的特点,回溯的时候U和U的子孙的LCA是U,U和U的兄弟结点的子孙 ...

  6. hihocoder 1873 ACM-ICPC北京赛区2018重现赛 D Frog and Portal

    http://hihocoder.com/problemset/problem/1873 时间限制:1000ms 单点时限:1000ms 内存限制:512MB 描述 A small frog want ...

  7. navicat 无法连接到腾讯云Mysql

    远程连接进入服务器 远程连接进入服务器之后,输入命令mysql -u root -p 之后输入mysql密码,进入mysql 命令环境 设置开启远程登录 GRANT ALL PRIVILEGES ON ...

  8. Spring @Value用法

    Spring 通过注解获取*.porperties文件的内容,除了xml配置外,还可以通过@value方式来获取. 使用方式必须在当前类使用@Component,xml文件内配置的是通过pakage扫 ...

  9. MySQL入门笔记 - 视图

    参考书籍<MySQL入门很简单> 1.视图定义 视图是从一个或者多个表中导出来的虚拟的表,透过这个窗口可以看到系统专门提供的数据,使用户可以只关心对自己有用的数据,方便用户对数据操作,同时 ...

  10. Meteor事件

    使用事件是非常简单的.我们将学习如何使用tag,class 和id作为事件选择器. 让我们创建HTML模板三大要素.第一个是 p 标签,第二个是 myClass 类,最后一个是myId. meteor ...