[bzoj4825]:[Hnoi2017]单旋
#include<iostream> #include<cstdio> #define getchar() (*S++) char B[1<<26],*S=B; #define INF 2000000000 #define MN 100000 using namespace std; inline int read() {int x = 0; char ch = getchar();while(ch < '0' || ch > '9')ch = getchar();while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x; }int n,fa[MN+5],val[MN+5],cnt=0,c[MN+5][2],rt=0,Q,s[MN+5],dep[MN+5],mn[MN+5],size[MN+5];inline void pushdown(int x) {int l=c[x][0],r=c[x][1];val[l]+=val[x];dep[l]+=val[x];mn[l]+=val[x];val[r]+=val[x];dep[r]+=val[x];mn[r]+=val[x];val[x]=0; }inline void update(int x) {int l=c[x][0],r=c[x][1];size[x]=size[l]+size[r]+1;mn[x]=dep[x];if(l) mn[x]=min(mn[x],mn[l]);if(r) mn[x]=min(mn[x],mn[r]); }void rotate(int x,int&k) {int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;if(y==k) k=x; else c[z][c[z][1]==y]=x;fa[x]=z;fa[y]=x;fa[c[x][r]]=y;c[y][l]=c[x][r];c[x][r]=y;update(y);update(x); }void splay(int x,int&k) {for(;x!=k;rotate(x,k))if(fa[x]!=k) rotate((c[fa[fa[x]]][1]==fa[x]^c[fa[x]][1]==x)?x:fa[x],k); }void ins(int&x,int S,int d,int last) {if(!x){x=++cnt;s[cnt]=S;dep[cnt]=mn[cnt]=d;size[cnt]=1;fa[cnt]=last;return;}ins(c[x][S>s[x]],S,d,x);update(x); }int Find_Before(int x,int S) {if(!x) return 0;if(val[x]) pushdown(x);if(s[x]>S) return Find_Before(c[x][0],S);return (Q=Find_Before(c[x][1],S))?Q:x; }int Find_After(int x,int S) {if(!x) return 0;if(val[x]) pushdown(x);if(s[x]<S) return Find_After(c[x][1],S);return (Q=Find_After(c[x][0],S))?Q:x; }int Find(int x,int rk) {if(val[x]) pushdown(x);int sz=size[c[x][0]]+1;if(sz==rk) return x;if(sz<rk) return Find(c[x][1],rk-sz);return Find(c[x][0],rk); }int FindLeft(int x,int d) {if(!x) return 0;if(val[x]) pushdown(x);if(min(mn[c[x][0]],dep[x])>=d) return FindLeft(c[x][1],d)+size[c[x][0]]+1;else return FindLeft(c[x][0],d); }int FindRight(int x,int d) {if(!x) return 0;if(val[x]) pushdown(x);if(min(mn[c[x][1]],dep[x])>=d) return FindRight(c[x][0],d)+size[c[x][1]]+1;else return FindRight(c[x][1],d); }inline int Split(int l,int r) {int Lt=Find(rt,l-1),Rt=Find(rt,r+1);splay(Lt,rt);splay(Rt,c[rt][1]);return c[c[rt][1]][0]; }inline void Modify(int l,int r,int ad) {int y=Split(l,r);val[y]+=ad;mn[y]+=ad;dep[y]+=ad; }void change(int x,int S) {if(val[x]) pushdown(x);if(s[x]==S) dep[x]=1;else change(c[x][S>s[x]],S);update(x); }int main() {fread(B,1,1<<26,stdin);n=read();ins(rt,-INF,INF,0);ins(rt,INF,INF,0);mn[0]=INF;for(int i=1;i<=n;++i){int op=read();if(op==1){int x=read(),bef=Find_Before(rt,x),aft=Find_After(rt,x);int D=max(bef>2?dep[bef]:0,aft>2?dep[aft]:0)+1;ins(rt,x,D,0);splay(cnt,rt);printf("%d\n",D);}if(!(op&1)){int x=Find(rt,2),y=min(FindLeft(rt,dep[x]),size[rt]-1)-1;printf("%d\n",dep[x]);Modify(2,size[rt]-1,1);if(y>1) Modify(2,y+1,-1);change(rt,s[x]);}if((op&1)&&op>1){int x=Find(rt,size[rt]-1),y=min(FindRight(rt,dep[x]),size[rt]-1)-1;printf("%d\n",dep[x]);Modify(2,size[rt]-1,1);if(y>1) Modify(size[rt]-y,size[rt]-1,-1);change(rt,s[x]);}if(op>=4){if(op==4) splay(Find(rt,2),rt);else splay(Find(rt,size[rt]-1),rt);int l=(op==5),r=l^1,y=c[rt][l];c[y][r]=c[rt][r];fa[y]=0;fa[c[rt][r]]=y;rt=y;val[rt]-=1;update(rt);}}return 0; }
转载于:https://www.cnblogs.com/FallDream/p/bzoj4825.html
[bzoj4825]:[Hnoi2017]单旋相关推荐
- [BZOJ4825][HNOI2017]单旋(线段树+Splay)
4825: [Hnoi2017]单旋 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 667 Solved: 342 [Submit][Status ...
- BZOJ4825: [Hnoi2017]单旋(Splay)
题面 传送门 题解 调了好几个小时--指针太难写了-- 因为只单旋最值,我们以单旋\(\min\)为例,那么\(\min\)是没有左子树的,而它旋到根之后,它的深度变为\(1\),它的右子树里所有节点 ...
- [HNOI2017]单旋
题意: 模拟一棵单旋splay,支持五种操作 \(\text{Solution:}\) 显然不是让你码一颗单旋splay(一条链卡爆你). 在草稿纸上画一画,模拟一遍,观察中序遍历下的深度变化,发现当 ...
- 平衡搜索树中的左单旋右单旋双旋
本文要点: 平衡搜索树的左单旋.右单旋.左右双旋.右左双旋 在平衡搜索树中进行插入结点时,有可能会破坏整棵树的平衡.为了保证平衡不被破坏,就要对一些节点进行旋转,从而来降低树的高度,这样也能保证树的平 ...
- 【C++】VAL树的旋转(左单旋、右单旋、双旋)
AVL树的旋转 在将旋转这一块,最好理解的就是图,所以我主要采取图解的方式,来讲述左单旋.右单旋.以及双旋. 在讲VAL树的旋转之前,先来了解一下VAL树的特性. AVL树的特性 AVL树是一个严格平 ...
- Java 平衡二叉树之单旋(左旋,右旋)与双旋
1.平衡二叉树 平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高. 具有以下特点:它是一 棵空树或它的左右两个 ...
- splay单旋与双旋
在贴吧看了个娱乐向的骗回复帖子,说双旋比单旋慢.好吧,我承认可能在某一次是这样.但别忘了,splay可是平摊时间复杂度的. 那为啥我们要双旋呢?如果你手动模拟四个以上的点的旋转,你会发现,如果单旋一条 ...
- JZOJ 7036. 2021.03.30【2021省赛模拟】凌乱平衡树(平衡树单旋+权值线段树)
JZOJ 7036. 2021.03.30[2021省赛模拟]凌乱平衡树 题目大意 给出两棵Treap,大小分别为 n , m n,m n,m,每个点的 p r i o r i t y priorit ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
最新文章
- Android和iOS那个好?
- 2019年最新最全运维技能图谱
- vue依赖缓存_Vue SSR服务端渲染之数据缓存
- 【COCOS CREATOR 系列教程之二】脚本开发篇事件监听、常用函数等示例整合
- php修改mysql数据库中的表格,如何修改mysql数据库表?
- LeetCode 702. 搜索长度未知的有序数组(二分查找)
- 25.C++- 泛型编程之函数模板(详解)
- oracle delete循环删除_oracle性能优化:高水位线(HWM)详解--如何计算HWM
- 有东西,可以倚老卖老,可以倚少卖少
- motrix下载没速度_再见迅雷!高颜值没广告的下载神器Motrix体验
- 大学计算机考试必备,大学计算机基础大一考试必备题库
- 异常值离群点检测算法---箱线图四分位检测
- HTML5 页面制作工具
- k8s 超详细总结,面试必问
- 域组策略与本地组策略
- 电脑台式计算机描述不可用,【计算机描述不可用】计算机描述不可用步骤_计算机分级不可用-系统城...
- 营销之父科特勒万字演讲实录:营销的未来(含PPT和视频回放)
- QVector使用示例
- Microsoft PlayReady DRM及其工作原理
- 那些年,我们一起参加过的高考
热门文章
- 前端基础——day1
- springboot整合shiro-关于登出时,redis中缓存没有清理干净的问题
- Spring Ioc 之 Bean的加载(1)(生命周期)
- 深入理解最大池化为什么能够实现不变性?
- C语言模拟实现(一)----- 优先权抢占式时间片调度算法
- ANDROID: 超级好用的ADB FORWARD命令
- 区块链 PoS 共识——Tendermint
- Linux kernel 3.10内核源码分析--进程退出exit_code
- JZOJ 5643. 【NOI2018模拟4.10】最小代价
- JZOJ 5437. 【NOIP2017提高A组集训10.31】Sequence