bzoj 1588 裸平衡树

//By BLADEVIL

#include <cstdio>

#include <set>

#define inf 1<<30

 

using namespace std;

 

int n,ans;

 

int main()

{

    int x;

    set<int>bt;

    bt.insert(inf); bt.insert(-inf);

    scanf("%d",&n);

    for (int i=1;i<=n;i++)

    {

        //printf(" %d\n",ans);

        if (scanf("%d",&x)==EOF) x=0;

        if (i==1) ans=x,bt.insert(x); else

        {

            int a,b;

            a=*bt.upper_bound(x); b=*(--bt.upper_bound(x));

            ans+=(a-x<x-b)?a-x:x-b;

            bt.insert(x);

        }

    }

    printf("%d\n",ans);

    return 0;

}

 

裸平衡树

 

/**************************************************************

    Problem: 1588

    User: BLADEVIL

    Language: Pascal

    Result: Accepted

    Time:440 ms

    Memory:852 kb

****************************************************************/

 

//By BLADEVIL

var

    n                       :longint;

    ans                     :longint;

    size, left, right, key  :array[0..40000] of longint;

    t, tot                  :longint;

    x                       :longint;

    a, b                    :longint;

    i                       :longint;

     

function min(a,b:longint):longint;

begin

    if a>b then min:=b else min:=a;

end;

 

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[left[t]]+size[right[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;

        left[t]:=0;

        right[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 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

    read(n);

    t:=0; tot:=0;

    read(x);

    ans:=x;

    insert(t,x);

    for i:=2 to n do

    begin

        read(x);

        a:=pred(t,x); b:=succ(t,x);

        if a=-1 then inc(ans,b-x) else

        if b=-1 then inc(ans,x-a) else

        ans:=ans+min(abs(a-x),abs(b-x));

        insert(t,x);

    end;

    writeln(ans);

end.

 

你可能感兴趣的:(ZOJ)