SBT(pet)

原题:HNOI2004 宠物收养所

方法:SBT 维护

program size_balanced_tree;{$inline on}
const
    maxn=80000;
type
    point=^longint;
var
    s,l,r,w:array[0..maxn] of longint; a,b:point;
    ans,m,t,k,now,root,sto:longint;
procedure left(var i:longint);inline;
var j:longint;
begin
    j:=r[i];r[i]:=l[j];l[j]:=i;
    s[j]:=s[i];s[i]:=s[l[i]]+s[r[i]]+1;i:=j;
end;
procedure right(var i:longint);inline;
var j:longint;
begin
    j:=l[i];l[i]:=r[j];r[j]:=i;
    s[j]:=s[i];s[i]:=s[l[i]]+s[r[i]]+1;i:=j;
end;
procedure maintain(var t:longint; flag:boolean);inline;
begin
    if not flag then begin
	if s[l[l[t]]]>s[r[t]] then right(t) else
	if s[r[l[t]]]>s[r[t]] then begin left(l[t]); right(t);end else exit;
    end else begin
	if s[r[r[t]]]>s[l[t]] then left(t) else
	if s[l[r[t]]]>s[l[t]] then begin right(r[t]); left(t);end else exit;
    end;
    maintain(l[t],false);
    maintain(r[t],true);
    maintain(t,false);
    maintain(t,true);
end;
procedure insert(var x:longint; const k:longint);
begin
    if x=0 then begin inc(sto); x:=sto; w[x]:=k; s[x]:=1; exit; end;
    inc(s[x]); if k<w[x] then insert(l[x],k) else insert(r[x],k);
    maintain(x,k>=w[x]);
end;
procedure delete(var x:longint);
begin
    if (l[x]=0)or(r[x]=0) then begin x:=l[x]+r[x]; exit; end;
    left(x);right(l[x]);delete(r[l[x]]);
end;
function pred(var x:longint; const k:longint):point;
begin
    if (x=0)or(k=w[x]) then exit(@x);
    if k<w[x] then pred:=pred(l[x],k)
    else begin
	pred:=pred(r[x],k);
	if pred^=0 then exit(@x);
    end;
end;
function succ(var x:longint; const k:longint):point;
begin
    if (x=0)or(k=w[x]) then exit(@x);
    if k>w[x] then succ:=succ(r[x],k)
    else begin
	succ:=succ(l[x],k);
	if succ^=0 then exit(@x);
    end;
end;
function getch:char; var k:byte;
begin
    for k:=1 to 5 do read(getch);
end;
procedure readspace; var ch:char;
begin repeat read(ch); until ch=' '; end;

begin
    assign(input,'input.txt'); reset(input); 
    assign(output,'output.txt'); rewrite(output);
    readln(m);for m:=1 to m do begin
	readln(t,k);if root=0 then now:=t;
	if t=now then begin insert(root,k); continue; end;
	a:=pred(root,k);
	b:=succ(root,k);
	if a^=0 then begin add(ans,w[b^]-k); delete(b^); end else
	if b^=0 then begin add(ans,k-w[a^]); delete(a^); end else
	if k-w[a^]<=w[b^]-k then
		    begin add(ans,k-w[a^]); delete(a^); end else
		    begin add(ans,w[b^]-k); delete(b^); end; 
    end;
    writeln(ans);
    close(input); close(output);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值