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.

 

你可能感兴趣的:(ZOJ)