算法模板——平衡树Treap
实现功能如下——1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
本程序的实现原理为Treap平衡树
详见BZOJ3224
var
i,j,k,l,m,n,head,ts:longint;f1:text;
a,b,fix,lef,rig:array[..] of longint;
procedure lt(var x:longint);inline;
var f,r:longint;
begin
if (x=) or (rig[x]=) then exit;
f:=x;r:=rig[x];
b[r]:=b[f];
b[f]:=b[lef[f]]++b[LEF[R]];
rig[f]:=lef[r];
lef[r]:=f;
x:=r;
end;
procedure rt(var x:longint);inline;
var f,l:longint;
begin
if (x=) or (lef[x]=) then exit;
f:=x;l:=lef[x];
b[l]:=b[f];
b[f]:=b[rig[f]]++b[rig[l]];
lef[f]:=rig[l];
rig[l]:=f;
x:=l;
end;
FUNCTION max(x,y:longint):longint;inline;
begin
if x>y then max:=x else max:=y;
end;
function min(x,y:longint):longint;inline;
begin
if x<y then min:=x else min:=y;
end;
procedure ins(var head:longint;x:longint);
begin
if head= then
begin
head:=x;
exit;
end;
if a[x]<a[head] then
begin
ins(lef[head],x);
b[head]:=b[lef[head]]+b[rig[head]]+;
if fix[lef[head]]<fix[head] then rt(head);
end
else
begin
ins(rig[head],x);
b[head]:=b[lef[head]]+b[rig[head]]+;
if fix[rig[head]]<fix[head] then lt(head);
end;
end;
function getp(head,x:longint):longint;
begin
if head= then exit();
if a[head]=x then exit(head);
if a[head]>x then exit(getp(lef[head],x)) else exit(getp(rig[head],x));
end;
procedure del(var head:longint);
var i,j,k,l,f,r:longint;
begin
if head= then exit;
if (lef[head]=) then
begin
b[head]:=b[rig[head]];
head:=rig[head];
exit;
end;
if rig[head]= then
begin
b[head]:=b[lef[head]];
head:=lef[head];
exit;
end;
if fix[lef[head]]>fix[rig[head]] then
begin
lt(head);
del(lef[head]);
b[head]:=b[lef[head]]+b[rig[head]]+;
end
else
begin
rt(head);
del(rig[head]);
b[head]:=b[lef[head]]+b[rig[head]]+;
end;
end;
procedure det(var head,x:longint);
begin
if head= then exit;
if x=head then
begin
del(head);
b[head]:=b[lef[head]]+b[rig[head]]+;
exit;
end;
if lef[head]=x then
begin
del(lef[head]);
b[head]:=b[lef[head]]+b[rig[head]]+;
exit;
end;
if rig[head]=x then
begin
del(rig[head]);
b[head]:=b[lef[head]]+b[rig[head]]+;
exit;
end;
if a[x]<a[head] then det(lef[head],x) else det(rig[head],x);
b[head]:=b[lef[head]]+b[rig[head]]+;
end;
procedure showoff(head:longint);
begin
if head= then exit;
showoff(lef[head]);
write(a[head],' ');
showoff(rig[head]);
end;
function getrank(head,x:longint):longint;
var k:longint;
begin
if head= then exit(-);
if x=a[head] then //亲们注意了,就是这个地方坑了我好久啊啊啊啊啊啊
begin
k:=getrank(lef[head],x);
if k=- then exit(b[lef[head]]+) else exit(k);
end
else
begin
if x<a[head] then
begin
exit(getrank(lef[head],x));
end
else
begin
k:=getrank(rig[head],x);
if k=- then exit(-) else exit(b[lef[head]]++k);
end;
end;
end;
function rankget(head,x:longint):longint;
begin
if head= then exit(maxlongint);
if (b[lef[head]]+)=x then exit(a[head]);
if (b[lef[head]]+)<x then exit(rankget(rig[head],x--b[lef[head]])) else exit(rankget(lef[head],x))
end;
function getsuc(head,x:longint):longint;
begin
if (head=) then exit(+maxlongint);
if (a[head]<=x) then exit(getsuc(rig[head],x)) else exit(min(a[head],getsuc(lef[head],x)));
end;
function getpre(head,x:longint):longint;
begin
if (head=) then exit(-maxlongint);
if (a[head]>=x) then exit(getpre(lef[head],x)) else exit(max(a[head],getpre(rig[head],x)));
end; begin
m:=;head:=;
randomize;
readln(n);
for i:= to n do
begin
read(l);
case l of
:begin
readln(j);
inc(m);
a[m]:=j;
fix[m]:=random(maxlongint);
lef[m]:=;rig[m]:=;b[m]:=;
ins(head,m);
end;
:begin
readln(j);
k:=getp(head,j);
det(head,k);
l:=;
end;
:BEGIN
readln(j);
k:=getrank(head,j);
writeln(k);
end;
:begin
readln(j);
writeln(rankget(head,j));
end;
:begin
readln(j);
writeln(getpre(head,j));
end;
:begin
readln(j);
writeln(getsuc(head,j));
end;
end; l:=;
end;
readln;
end.
算法模板——平衡树Treap的更多相关文章
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 普通平衡树Treap(含旋转)学习笔记
浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...
- 2021.12.06 平衡树——Treap
2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...
- hiho #1325 : 平衡树·Treap
#1325 : 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? ...
- 匈牙利 算法&模板
匈牙利 算法 一. 算法简介 匈牙利算法是由匈牙利数学家Edmonds于1965年提出.该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. 二分图的定义: 设G=(V,E)是一个 ...
- Tarjan 算法&模板
Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...
- hdu 2255 奔小康赚大钱--KM算法模板
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...
- POJ 1273 Drainage Ditches(网络流dinic算法模板)
POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...
随机推荐
- Flex中操作XML的E4X方法
用于处理 XML 的 E4X 方法 Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 ECMAScript for XML 规范定义了一组用于使用 XML 数据的类 ...
- JSP获取绝对物理地址
session.getServletContext().getRealPath(""); 但是 getRealPath("a"+File.separator); ...
- 微信小程序t填坑之旅一(接入)
一.小程序简介 小程序是什么? 首先"程序"这两个字我们不陌生.看看你手机上的各个软件,那就是程序.平时的程序是直接跑在我们原生的操作系统上面的.小程序是间接跑在原生系统上的.因为 ...
- java算法 蓝桥杯 乘法运算
问题描述 编制一个乘法运算的程序. 从键盘读入2个100以内的正整数,进行乘法运算并以竖式输出. 输入格式 输入只有一行,是两个用空格隔开的数字,均在1~99之间(含1和99). 输出格式 输出为4行 ...
- css3 2d转换3d转换以及动画的知识点汇总
css3 2d转换 2d转换的方法: 1.移动 translate(x, y) 可以改变元素的位置,x.y可为负值: 2.缩放 scale(x, y) 可以对元素进行水平和垂直方向的缩放,x.y的取值 ...
- IOS获取经度纬度
仔细研究了一下SDK文档,再结合网上的方法,写了这一个简单的获取经纬度的方法,大家看看就好. 首先要导入CoreLocation.Frame 包 .h 文件 1 2 3 4 5 6 7 8 9 #im ...
- [转载] ping和telnet的区别
转载自:http://www.cnblogs.com/Jtianlin/p/4045021.html windown7下打开telnet功能: 控制面板 --- > 程序(小图标下直接到[程序和 ...
- Linux的CentOS7系统下配置LNMP
友情提示:在执行以下操作之前,请确保您已经安装了centos7,因为以下所有操作均是在centos7下操作完成的. 1.首先要停掉本机自带的防火墙,再配置iptables,开放21/22/80/808 ...
- oracle 游标的使用
额,一直提起游标就头疼,总感觉是很高大上的东西,望而却步... 今天要做的东西涉及到了实时更新数据,要用到JOB 存储过程 游标 通过在网上查资料,请教同事,也开始继续深入oracle,,,,小菜啊 ...
- (一) 从Angular1到Angular2的杂谈
使用了angular1一年下来,完成了若干项目,承蒙此框架的强大带来了不算差的项目编写体验,但1.*版本的angular,确实是有厉害的地方也有其尴尬的地方,包括较多数据的渲染的性能问题,还有就是可能 ...