poj3481

平衡树的题,应该还有什么最大堆最小堆的解法

题目描述 http://poj.org/problem?id=3481

题目大意:给你一系列操作,0代表读入终止,1代表添加一个编号为k,权值为p的点,2代表输出权值最大点的编号并删除该点,3代表输出权值最小的点并删除该节点。

 

我用的treap,基本上还可以,会一种平衡树是必要的

详细解释在代码内部

skysun原创,http://www.cnblogs.com/skysun

View Code
  1 program sky;
2 const
3 maxn = 1000000;
4 type
5 aa = array[0..1000000] of record
6 l,r,w,b,c : longint;
7 end;
8 var
9 p,w,k : longint;
10 root,tp,tot : longint;
11 a : aa;
12
13 procedure left(var e :longint );{几乎每个过程都要var,因为改变了树的形态,需要传出去}
14 var j : longint;
15 begin
16 j:=a[e].l;
17 a[e].l:=a[j].r;
18 a[j].r:=e;
19 e:=j;
20 end; { left }
21 procedure right(var e :longint );
22 var j : longint;
23 begin
24 j:=a[e].r;
25 a[e].r:=a[j].l;
26 a[j].l:=e;
27 e:=j;
28 end; { right }
29
30 procedure ins(var e: longint );{这也要var,因为它也会改变树的形态,使根改变}
31 begin
32 if e=0 then
33 begin
34 inc(tot);
35 a[tot].w:=w; a[tot].b:=random(maxn); a[tot].c:=k;
36 a[tot].l:=0; a[tot].r:=0;
37 e:=tot;
38 exit;
39 end;
40 if a[e].w>=w then
41 begin
42 ins(a[e].l);
43 if a[e].b>a[a[e].l].b then left(e);
44 exit;
45 end;
46 if a[e].w<w then
47 begin
48 ins(a[e].r);
49 if a[e].b>a[a[e].r].b then right(e);
50 exit;
51 end;
52 end; { ins }
53
54 procedure delete(var e :longint);
55 begin
56 if a[e].w=a[tp].w then
57 begin
58 if a[e].l*a[e].r=0 then begin e:=a[e].l+a[e].r; exit; end;
59 if a[a[e].l].b<a[a[e].r].b then
60 begin {左旋之后原结点会到新的根的右边}
61 left(e); {所以左旋,向右递归}
62 delete(a[e].r);
63 exit;
64 end else
65 begin
66 right(e); {同上}
67 delete(a[e].l);
68 exit;
69 end;
70 end;
71 if a[tp].w>a[e].w then begin delete(a[e].r); exit; end;
72 if a[tp].w<a[e].w then begin delete(a[e].l); exit; end;
73 end; { delete }
74
75 function getmax(e :longint ):longint;
76 begin
77 while a[e].r<>0 do e:=a[e].r;
78 exit(e); {返回在树里的编号,不要返回读入的编号,不然可以输出,但delete就没办法了}
79 end; { getmax }
80 function getmin(e :longint ):longint;
81 begin
82 while a[e].l<>0 do e:=a[e].l;
83 exit(e);
84 end; { getmin }
85
86 begin
87 assign(input,'tiaoshi.in'); reset(input);
88 read(p);
89 randomize;
90 root:=0;
91 while p<>0 do
92 begin
93 case p of
94 1 : begin readln(k,w); ins(root); end; {这里每一个过程都传root,因为平衡树跟在变}
95 2 : begin tp:=getmax(root); writeln(a[tp].c); delete(root); end;
96 3 : begin tp:=getmin(root); writeln(a[tp].c); delete(root); end;
97 end; { case }
98 read(p);
99 end;
100 end.



posted @ 2012-04-01 09:15  SunSky...  阅读(201)  评论(0编辑  收藏  举报