bzoj 3224 裸平衡树

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

/**************************************************************
    Problem: 3224
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:660 ms
    Memory:15852 kb
****************************************************************/
 
//By BLADEVIL
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;
    read(n);
    for i:=1 to n do
    begin
        read(x,y);
        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  阅读(389)  评论(0编辑  收藏  举报