普通平衡树 Splay
Code:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=400006;
int ch[maxn][2],f[maxn],siz[maxn],num[maxn],val[maxn];
int root,cnt;
int get(int x){return ch[f[x]][1]==x;}
void pushup(int x){siz[x]=num[x]+siz[ch[x][0]]+siz[ch[x][1]];}
void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
ch[x][which^1]=old,f[old]=x,f[x]=oldf;
if(oldf)ch[oldf][ch[oldf][1]==old]=x;
pushup(old);pushup(x);
}
int findx(int x){
int p=root;
while(val[p]!=x)p=ch[p][x>val[p]];
return p;
}
void splay(int x,int& tar){
int a=f[tar];
for(int fa;(fa=f[x])!=a;rotate(x))
if(f[fa]!=a)rotate(get(x)==get(fa)?fa:x);
tar=x;
}
int x_rank(int x){
splay(findx(x),root);return siz[ch[root][0]]+1;
}
int rank_x(int x){
int p=root;
while(1){
if(x<=siz[ch[p][0]])p=ch[p][0];
else {
x-=(siz[ch[p][0]]+num[p]);
if(x<=0){splay(p,root);return val[p];}
p=ch[p][1];
}
}
}
int pre_x(int x){
int ans;
int p=root;
while(p){
if(val[p]<x){ans=val[p];p=ch[p][1];}
else p=ch[p][0];
}
return ans;
}
int aft_x(int x){
int ans;
int p=root;
while(p){
if(val[p]>x){ans=val[p],p=ch[p][0];}
else p=ch[p][1];
}
return ans;
}
void insert_x(int x){
if(!root){
++cnt;root=cnt,val[root]=x,num[root]=1;pushup(root);return;
}
int p,fa;
p=fa=root;
while(p&&val[p]!=x)fa=p,p=ch[p][x>val[p]];
if(!p){
++cnt;val[cnt]=x,num[cnt]=1,f[cnt]=fa,ch[fa][x>val[fa]]=cnt;
pushup(cnt);splay(cnt,root);return;
}
++num[p];pushup(p);splay(p,root);
}
void delete_x(int x){
int p=findx(x);splay(p,root);
if(num[root]>1){--num[root];pushup(root);return;}
if(!ch[root][0]&&!ch[root][1])root=0;
else if(!ch[root][0])root=ch[root][1],f[root]=0;
else if(!ch[root][1])root=ch[root][0],f[root]=0;
else{
p=ch[root][0];
while(ch[p][1])p=ch[p][1];
splay(p,ch[root][0]);
ch[p][1]=ch[root][1];f[ch[p][1]]=p,f[p]=0;pushup(p);
root=p;
}
}
int main(){
int N;scanf("%d",&N);
for(int i=1;i<=N;++i)
{
int opt,x;scanf("%d%d",&opt,&x);
if(opt==1)insert_x(x);
if(opt==2)delete_x(x);
if(opt==3)printf("%d\n",x_rank(x));
if(opt==4)printf("%d\n",rank_x(x));
if(opt==5)printf("%d\n",pre_x(x));
if(opt==6)printf("%d\n",aft_x(x));
}
return 0;
}
普通平衡树 Splay的更多相关文章
- hiho #1329 : 平衡树·Splay
#1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...
- 【BZOJ3224】Tyvj 1728 普通平衡树 Splay
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...
- Hihocoder 1329 平衡树·Splay(平衡树)
Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- 平衡树——splay 三
前文链接: 平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) 平衡树--splay 二 - yi_fan0305 - 博客园 (cnblogs.com) 再补 ...
- 平衡树——splay 二
上文传送门:平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) OK,我们继续上文,来讲一些其他操作. 七.找排名为k的数 和treap的操作很像,都是通过比较 ...
- 平衡树——splay 一
splay 一种平衡树,同时也是二叉排序树,与treap不同,它不需要维护堆的性质,它由Daniel Sleator和Robert Tarjan(没错,tarjan,又是他)创造,伸展树是一种自调整二 ...
- BZOJ3223: Tyvj 1729 文艺平衡树 [splay]
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3595 Solved: 2029[Submit][Sta ...
随机推荐
- js借助JSONP实现百度搜索框提示效果
主要借助百度搜索的API,调用时会存在跨域问题,需要通过JSONP来解决这个问题,代码如下(代码中部分使用ES6语法): HTML <input type="text" id ...
- delphi主i窗口中实现多页面管理效果
MainForm上加Panel,把Panel的DockSite设为True, 把窗口FB_orderManage的DragKind设为dkDock, DragMode设为dmAuromatic 在M ...
- 【Codeforces 350B】Resort
[链接] 我是链接,点我呀:) [题意] [题解] 我们可以把原图的边都反向一下. 然后以每个休息点作为起点,进行dfs. 每次在扩展节点y的时候,要求这个点y必须只有一个出度,然后就能走多远就走多远 ...
- C++管理指针成员
1.C++中一般採用以下三种方法之中的一个管理指针成员: (1)指针成员採取常规行为. 这种类具有指针的全部缺陷:具有指针成员且使用默认复制构造函数和赋值操作符,无法避免悬垂指针(两个对象的指针成员指 ...
- 实战c++中的vector系列--vector应用之STL的find、find_if、find_end、find_first_of、find_if_not(C++11)
使用vector容器,即避免不了进行查找,所以今天就罗列一些stl的find算法应用于vector中. find() Returns an iterator to the first element ...
- OC中使用UI自己定义控件实现计算器的设计(版本号1简单的加减乘除,连加,连减,连除,连乘)
OC中使用UI自己定义控件实现计算器的设计(版本号1简单的加减乘除,连加.连减,连除,连乘) #import <UIKit/UIKit.h> @interface ViewControll ...
- luogu2714 四元组统计 莫比乌斯反演 组合数
题目大意 给出一段序列,求其中最大公约数为1的四元组的个数. 思路 我们要用到反演.正难则反的思想.对于每一个大于1的数字\(x\),求出最大公约数为\(x\)的四元组的个数\(g(x)\),然后用排 ...
- poj--2236--棋盘问题(dfs)
棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 31183 Accepted: 15469 Descriptio ...
- [BZOJ 3387] Fence Obstacle Course
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3387 [算法] f[i][0]表示从第i个栅栏的左端点走到原点的最少移动步数 f[i ...
- 2017-3-12 leetcode 167 209 216
---恢复内容开始--- 对于每次开机avast喊出的“已经检测到危害”实在忍无可忍了(它只能检测到不能根除很气..)于是重装了系统,回到了win10感觉不赖. =================== ...