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,因为值是会改变的