http://poj.org/problem?id=3481
题目大意:给你一系列操作,0代表读入终止,1代表添加一个编号为k,权值为p的点,2代表输出权值最大点的编号并删除该点,3代表输出权值最小的点并删除该节点。
treap的操作方法就不具体说了,只解释一些地方,见代码
program haha;
type
node = record
ls,rs,r,data,num : longint;
end;
var
a : array[0..1000005] of node;
p,i,j,k,x : longint;
y,t,tot,root : longint;
procedure left(var x: longint);
var
t : longint;
begin
t:=a[x].ls;
a[x].ls:=a[t].rs;
a[t].rs:=x;
x:=t;
end; { left }
procedure right(var x : longint);
var
t : longint;
begin
t:=a[x].rs;
a[x].rs:=a[t].ls;
a[t].ls:=x;
x:=t;
end; { right }
procedure insert(var x,k,y: longint);
begin
if x=0 then
begin
inc(tot);
x:=tot;
a[x].data:=y;
a[x].ls:=0;
a[x].rs:=0;
a[x].num:=k;
a[x].r:=random(1000000);
exit;
end;
if y>a[x].data then
begin
insert(a[x].rs,k,y);//返回值给a[x].rs赋值,从而构建出树
if a[a[x].rs].r>a[x].r then{!}
right(x);
exit;
end;
if y<a[x].data then
begin
insert(a[x].ls,k,y);
if a[a[x].ls].r>a[x].r then
left(x);
exit;
end;
end; { insert }
procedure delete(var x,k : longint);
begin
if a[x].data=k then
begin
if (a[x].ls=0) or (a[x].rs=0) then
begin
if a[x].ls=0 then
begin
x:=a[x].rs;
exit;
end;
if a[x].rs=0 then
begin
x:=a[x].ls;
exit;
end;
end;
if a[a[x].ls].r>a[a[x].rs].r then//如果该节点儿子节点不为空,就旋转,将所要删除的节点旋转到下面,直到该点有叶子
begin
left(x);
delete(a[x].rs,k);
exit;
end;
if a[a[x].rs].r>a[a[x].ls].r then{!}//标记!的两个地方是不一样的:1.插入节点,只需调整插入的和原有的。2.删除节点,为了保证优先级排列的顺序,且由于该节点要删除,所以比较儿子节点再旋转
begin
right(x);
delete(a[x].ls,k);
exit;
end;
end;
if a[x].data>k then
delete(a[x].ls,k)
else
delete(a[x].rs,k);
end; { delete }
function findmin(x : longint):longint;
begin
if a[x].ls=0 then
exit(x);
if a[x].ls<>0 then
exit(findmin(a[x].ls));
end; { findmin }
function findmax(x : longint):longint;
begin
if a[x].rs=0 then
exit(x);
if a[x].rs<>0 then
exit(findmax(a[x].rs));
end; { findmax }
begin
assign(input,'sdf.in'); reset(input);
randomize;
root:=0;
read(p);
while p<>0 do
begin
if p=1 then
begin
readln(x,y);
insert(root,x,y);
end;
if p=2 then
begin
t:=findmax(root);//不能从1开始找,因为root的值是改变的,比如,根节点只有左儿子,那么就会删除根节点,此时root的值就会改变
writeln(a[t].num);
delete(root,a[t].data);
end;
if p=3 then
begin
t:=findmin(root);
writeln(a[t].num);
delete(root,a[t].data);
end;
read(p);
end;
close(input);
end.//最需要注意的是,所有的过程都需要用var,因为值是会改变的
浙公网安备 33010602011771号