## bzoj 3224 裸平衡树

裸的平衡树，可以熟悉模板用，写题写不出来的时候可以A以下缓解下心情。

/**************************************************************
Problem: 3224
Language: Pascal
Result: Accepted
Time:660 ms
Memory:15852 kb
****************************************************************/

var
n                       :longint;
i                       :longint;
x, y                    :longint;
t, tot                  :longint;
size, key, left, right  :array[0..1000010] of longint;

procedure left_rotate(var t:longint);
var
k                       :longint;
begin
k:=right[t];
right[t]:=left[k];
left[k]:=t;
size[k]:=size[t];
size[t]:=size[right[t]]+size[left[t]]+1;
t:=k;
end;

procedure right_rotate(var t:longint);
var
k                       :longint;
begin
k:=left[t];
left[t]:=right[k];
right[k]:=t;
size[k]:=size[t];
size[t]:=size[left[t]]+size[right[t]]+1;
t:=k;
end;

procedure maintain(var t:longint;flag:boolean);
begin
if not flag then
begin
if size[left[left[t]]]>size[right[t]] then
right_rotate(t) else
if size[right[left[t]]]>size[right[t]] then
begin
left_rotate(left[t]);
right_rotate(t);
end else exit;
end else
begin
if size[right[right[t]]]>size[left[t]] then
left_rotate(t) else
if size[left[right[t]]]>size[left[t]] then
begin
right_rotate(right[t]);
left_rotate(t);
end else exit;
end;
maintain(left[t],false);
maintain(right[t],true);
maintain(t,true);
maintain(t,false);
end;

procedure insert(var t:longint;v:longint);
begin
if t=0 then
begin
inc(tot);
t:=tot;
right[t]:=0;
left[t]:=0;
size[t]:=1;
key[t]:=v;
end else
begin
inc(size[t]);
if v<key[t] then insert(left[t],v) else insert(right[t],v);
maintain(t,v>=key[t]);
end;
end;

function delete(var t:longint;v:longint):longint;
begin
dec(size[t]);
if (v=key[t]) or (v>key[t]) and (right[t]=0) or (v<key[t]) and (left[t]=0) then
begin
delete:=key[t];
if (left[t]=0) or (right[t]=0) then
t:=left[t]+right[t] else
key[t]:=delete(left[t],v+1);
end else
if v<key[t] then delete:=delete(left[t],v) else delete:=delete(right[t],v);
end;

function rank(var t:longint;v:longint):longint;
begin
if t=0 then exit(1);
if key[t]>=v then
rank:=rank(left[t],v) else
rank:=rank(right[t],v)+size[left[t]]+1;
end;

function select(var t:longint;v:longint):longint;
begin
if size[left[t]]+1=v then exit(key[t]);
if size[left[t]]+1<v then
select:=select(right[t],v-size[left[t]]-1) else
select:=select(left[t],v);
end;

function pred(var t:longint;v:longint):longint;
begin
if t=0 then exit(-1);
if key[t]>=v then pred:=pred(left[t],v) else
begin
pred:=pred(right[t],v);
if pred=-1 then pred:=key[t];
end;
end;

function succ(var t:longint;v:longint):longint;
begin
if t=0 then exit(-1);
if key[t]<=v then succ:=succ(right[t],v) else
begin
succ:=succ(left[t],v);
if succ=-1 then succ:=key[t];
end;
end;

begin
t:=0;
tot:=0;
for i:=1 to n do
begin
case x of
1:insert(t,y);
2:y:=delete(t,y);
3:writeln(rank(t,y));
4:writeln(select(t,y));
5:writeln(pred(t,y));
6:writeln(succ(t,y));
end;
end;
end.

posted on 2013-12-04 09:42  BLADEVIL  阅读(388)  评论(0编辑  收藏  举报