皆さん、こんにちは。上一篇文章,我们讲了Splay如何实现。这一篇我们来让我们的伸展树短一点。

上一篇Splay讲解的链接:リンク

首先还是变量的定义,在这里呢,我把一些小函数也用Define来实现了。

1).变量定义和小函数。

#include<cstdio>
using namespace std;
using namespace std;
const int MAXN=1e5+5;
const int INF=1<<30;
struct Floor{ int Val,Fa,Size,Recy,Ch[2];}T[MAXN];//定义伸展树的结构体。
int N,Opt,X,NodeNum,TSize;//一些基础变量。
//定义根为零结点的右儿子。
#define Root RS(0)
//用Define来表示各各变量。
#define Val(X) T[X].Val
#define LS(X) T[X].Ch[0]
#define RS(X) T[X].Ch[1]
#define Fa(X) T[X].Fa
#define Recy(X) T[X].Recy
#define Size(X) T[X].Size
//更新函数
#define Update(X) Size(X)=Size(LS(X))+Size(RS(X))+Recy(X)
//关系函数
#define Ident(X) (RS(Fa(X))==X)
//连接函数
#define Connect(X,Y,Son) T[Fa(X)=Y].Ch[Son]=X

2).旋转函数

void Rotate(int X){
int YSon=Ident(X),Y=Fa(X),RSon=Ident(Y),R=Fa(Y),XSon=YSon^1,B=T[X].Ch[XSon];//记录位置和关系。
Connect(B,Y,YSon);Connect(X,R,RSon);Connect(Y,X,XSon);//旋转三板斧。
Update(Y);Update(X);//更新。
}

3).伸展函数

void Splay(int From,int To){
To=Fa(To);
while(Fa(From)!=To){
int Up=Fa(From);
if(Fa(Up)!=To) Ident(From)^Ident(To) ? Rotate(From):Rotate(Up);//判断是“之”字形还是“一”字型。
Rotate(From);
}
}

4).查找函数

int Find(int Value){
int Now=Root;
while(Now){
if(Value==Val(Now)){ Splay(Now,Root);return Now;}
Now=T[Now].Ch[Value>Val(Now)];//判断Now向左还是向右。
}
return 0;
}

5).创造结点

void CreNode(int Value,int Father){
NodeNum++;
Val(NodeNum)=Value;
Fa(NodeNum)=Father;
Size(NodeNum)=Recy(NodeNum)=1;
}

6).创造结点

int Insert(int Value){
if(!TSize){
TSize++;
Root=NodeNum+1;
CreNode(Value,0);
return NodeNum;
}
TSize++;
int Now=Root;
while(Now){
Size(Now)++;
if(Val(Now)==Value){ Recy(Now)++;return Now;}
int Next=Value<T[Now].Val ? 0:1;
if(!T[Now].Ch[Next]){
T[Now].Ch[Next]=NodeNum+1;
CreNode(Value,Now);
return NodeNum;
}
Now=T[Now].Ch[Next];
}
return 0;
}

7).创造结点

void Push(int Value){ int AddNode=Insert(Value);Splay(AddNode,Root);}

8).删除结点

void Destroy(int X){ Val(X)=Fa(X)=Size(X)=Recy(X)=LS(X)=RS(X)=0;}

9).删除结点

void Pop(int Value){
int KillNode=Find(Value);
if(!KillNode) return;
TSize--;
if(Recy(KillNode)>1){ Recy(KillNode)--;Size(KillNode)--;return;}
else if(!LS(KillNode)){ Root=RS(KillNode);Fa(Root)=0;}
else{
int LMAX=LS(KillNode);
while(RS(LMAX)) LMAX=RS(LMAX);
int R=RS(KillNode);
Splay(LMAX,LS(KillNode));
Connect(R,LMAX,1);Connect(LMAX,0,1);
Update(LMAX);
}
Destroy(KillNode);
}

10).查找值为X的排名

int Rank(int Value){
int Now=Root,Ans=1;
while(Now){
if(Value==Val(Now)){
Ans+=Size(LS(Now));
Splay(Now,Root);
return Ans;
}else{
Ans=Ans+(Value>Val(Now))*(Size(LS(Now))+Recy(Now));
Now=T[Now].Ch[Value>Val(Now)];
}
}
return 0;
}

11).查找第X小的数

int Atrank(int X){
if(X>TSize) return 0;
int Now=Root;
while(Now){
if(Size(LS(Now))<X && X<=Size(Now)-Size(RS(Now))){
Splay(Now,Root);
return Val(Now);
}else if(X<=Size(LS(Now))) Now=LS(Now);
else{
X=X-(Size(Now)-Size(RS(Now)));
Now=RS(Now);
}
}
return 0;
}

12).查找值为X的前驱

int Lower(int Value){
int Now=Root,Ans=-INF;
while(Now){
if(Value>Val(Now) && Val(Now)>Ans) Ans=Val(Now);
Now=T[Now].Ch[Value>Val(Now)];
}
return Ans;
}

13).查找值为X的后继

int Upper(int Value){
int Now=Root,Ans=INF;
while(Now){
if(Value<Val(Now) && Val(Now)<Ans) Ans=Val(Now);
Now=T[Now].Ch[Value>=Val(Now)];
}
return Ans;
}

14).主函数

int main(){
scanf("%d",&N);
while(N--){
scanf("%d%d",&Opt,&X);
if(Opt==1) Push(X);
else if(Opt==2) Pop(X);
else if(Opt==3) printf("%d\n",Rank(X));
else if(Opt==4) printf("%d\n",Atrank(X));
else if(Opt==5) printf("%d\n",Lower(X));
else printf("%d\n",Upper(X));
}
return 0;
}

再悄悄说一声,把上面所有的代码拼起来也可以AC平衡树模板题。

Splay代码简化版的更多相关文章

  1. 及其简短的Splay代码

    #include <stdio.h> #include <queue> #include <algorithm> #include <stdlib.h> ...

  2. 普通平衡树与文艺平衡树的splay代码

    主要综合借鉴了yyb和马前卒两位大佬的. //普通平衡树 #include <cstdio> #include <cctype> #include <cstring> ...

  3. java:struts2.3框架1(struts2快速配置,各文件之间的关系,基础代码简化版,XML中的通配符)

    1.struts2快速配置: A.到http://struts.apache.org下载struts2开发包struts-2.3.32-all.zip B.新建web项目并添加struts2依赖的ja ...

  4. 算法笔记--Splay && Link-Cut-Tree

    Splay 参考:https://tiger0132.blog.luogu.org/slay-notes 普通模板: ; ], val[N], cnt[N], fa[N], sz[N], lazy[N ...

  5. 【Luogu】P1486郁闷的出纳员(Splay)

    题目链接 名副其实的调了一下午…… 每做一道题都是对我那不规范的Splay代码的刀刻斧凿一般的修正啊…… Splay.如果有一批员工不干了,那就找还能干的薪水最少的员工,把它splay到根,删除它的左 ...

  6. codevs 1743 反转卡片 rope or splay

    [codevs1743]反转卡片 题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数 ...

  7. SPOJ - QMAX3VN (4350) splay

    SPOJ - QMAX3VN 一个动态的序列 ,在线询问某个区间的最大值.关于静态序列的区间最值问题,用ST表解决,参考POJ 3264 乍一看上去 splay可以轻松解决.书上说可以用块状链表解决, ...

  8. Bzoj1208 [HNOI2004]宠物收养所

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 7457  Solved: 2960 Description 最近,阿Q开了一间宠物收养所.收养所提供两 ...

  9. NOI2004 郁闷的出纳员

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

随机推荐

  1. Dynamics 365 基于 Sql Server 2017 安装 报表 问题

    如果使用SQL2017 安装D365 会发现 SSRS与AD不能在同一台服务器上,因为无法安装SSRS,而无SSRS 则D365是无法继续安装的. 所以解决方法有二个: 1.另外准备一台服务器,不需要 ...

  2. java基础篇 之 super关键字的理解

    ​ 之前一直认为,super指向的是父类对象.到今天,仔细查询了资料,自己做了实验,确认这个结论是不对的.我们分一下几个点讨论下: super的作用: 第一种:用来访问父类被隐藏的成员变量 第二种:用 ...

  3. Unity ugui拖动控件(地图模式与物件模式)

    拖动在游戏中使用频繁,例如将装备拖动到指定的快捷栏,或者大地图中拖动以查看局部信息等. Unity的EventSystems中可以直接继承几个接口来实现拖动功能,如下: namespace Unity ...

  4. repo使用总结—从入门到入门

    文章目录 1 what's repo 2 官方文档 Repo 命令参考资料 help 帮助 init 初始化 sync 同步所有项目文件 upload 提交更改 diff download foral ...

  5. IDEA打包JavaWeb项目

    IDEA打包JavaWeb项目 步骤: 1.配置项目->2.Build Artifacts->3.找到.war文件 具体操作: 首先,单击顶部工具栏的“File”选项,在弹出选项中选择“P ...

  6. 集群、分布式、SOA、微服务、webService等思想的整理

    引子:前几天甲方问我,他用wpf弄个界面,能不能通过其他语言给他传输数据,我由此想到了webservice(此时此刻,我也没有用过webServices),作日翻阅了一些资料,对这块技术有了个大概的了 ...

  7. layui编辑商品时,怎么使用下拉菜单显示商品默认分类的问题

    //加载商品默认的分类$.get('/admin/category/selec/' + {$simple.0.first_pid},function(msg){ $("#two_cate&q ...

  8. python之文件操作模块(os和shutil)

      1.os.name #操作系统类型 如果是posix,说明系统是liunx.Unix或Mac OS X,如果是nt,就是windows2.os.enviro #操作系统中定义的环境变量3.os.e ...

  9. Arthas 使用(二) —— 应用场景

    1. ognl获取bean SpringContextUtil,通常代码中会有类似这样的工具类用来获取 bean 实例 @Component public class SpringContextUti ...

  10. 5.5 Go defer

    5.5 Go defer 程序开发中经常要创建资源(数据库初始化连接,文件句柄,锁等),在程序执行完毕都必须得释放资源,Go提供了defer(延时机制)更方便.更及时的释放资源. 1.内置关键字def ...