首页 > 代码库 > HNOI2002营业额统计(平衡树)

HNOI2002营业额统计(平衡树)

标准的平衡树。

贴个splay吧

var
 v,l,r,fa:array[0..100000] of longint;
 root,x,i,n,ans:longint;
procedure zig(x:longint);
 var y,z:longint;
 begin
 y:=fa[x];z:=fa[y];
 if root=y then root:=x;
 l[y]:=r[x];
 if r[x]<>0 then fa[r[x]]:=y;
 r[x]:=y;
 fa[y]:=x;
 fa[x]:=z;
 if z=0 then exit;
 if l[z]=y then l[z]:=x else r[z]:=x;
 end;
procedure zag(x:longint);
 var y,z:longint;
 begin
 y:=fa[x];z:=fa[y];
 if root=y then root:=x;
 r[y]:=l[x];
 if l[x]<>0 then fa[l[x]]:=y;
 l[x]:=y;
 fa[y]:=x;
 fa[x]:=z;
 if z=0 then exit;
 if l[z]=y then l[z]:=x else r[z]:=x;
 end;
procedure splay(x:longint);
 var y,z:longint;
 begin
 while x<>root do
  begin
  y:=fa[x];
  if y=root then
   begin
   if x=l[y] then zig(x) else zag(x);
   exit;
   end;
  z:=fa[y];
  if l[y]=x then
   if l[z]=y then
    begin
     zig(y);zig(x)
    end
   else
    begin
     zig(x);zag(x);
    end
  else
   if r[z]=y then
    begin
     zag(y);zag(x);
    end
   else
    begin
     zag(x);zig(x);
    end;
  end;
 end;
procedure insert(x,k:longint);
 var i,j:longint;
 begin
 if root=0 then
  begin
  root:=k;
  v[k]:=x;l[k]:=0;r[k]:=0;fa[k]:=0;
  exit;
  end;
 i:=root;
 v[k]:=x;
 while true do
  begin
  if x<=v[i] then j:=l[i] else j:=r[i];
  if j=0 then
   begin
    if x<=v[i] then l[i]:=k else r[i]:=k;
    fa[k]:=i;
    break;
   end;
  i:=j;
  end;
 splay(k);
 end;
function min(x,k:longint):longint;
 var i,j,tmp:longint;
 begin
 tmp:=maxlongint;
 i:=l[k];
 while i<>0 do
  begin
   if abs(v[i]-x)<tmp then begin tmp:=abs(v[i]-x);j:=i;end;
   i:=r[i];
  end;
 i:=r[k];
 while i<>0 do
  begin
   if abs(v[i]-x)<tmp then begin tmp:=abs(v[i]-x);j:=i;end;
   i:=l[i];
  end;
 splay(j);
 exit(tmp);
 end;
begin
 read(n);
 ans:=0;
 for i:=1 to n do
  begin
   read(x);
   insert(x,i);
   if i<>1 then ans:=ans+min(x,i) else ans:=x;
  end;
 writeln(ans);
end.