您的位置:首页 > 其它

bzoj1208: [HNOI2004]宠物收养所 (sbt)

2015-02-25 00:56 381 查看
切傻逼题还能wa那么多次我也是醉了

好啦其实是sbt都不会敲了(一直用神器treap)

重点是研究了下陈大神的删除,以前treap的删除都是直接旋转去删的……

还是treap大法好&……

题解还用写么?就是找前驱找后继然后判断一下

const
maxn=300000;
mm=1<<28;
mmm=1000000;

var
left,right,value,s:array[0..maxn]of longint;
ans,n,m,i,j,k,l,t,tot,now:longint;

function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end;

function max(x,y:longint):longint;
begin
if x<y then exit(y);
exit(x);
end;

procedure lt(var x:longint);
var
k:longint;
begin
k:=right[x];
right[x]:=left[k];
left[k]:=x;
s[k]:=s[x];
s[x]:=s[left[x]]+1+s[right[x]];
x:=k;
end;

procedure rt(var x:longint);
var
k:longint;
begin
k:=left[x];
left[x]:=right[k];
right[k]:=x;
s[k]:=s[x];
s[x]:=s[left[x]]+1+s[right[x]];
x:=k;
end;

procedure maintain(var t:longint);
begin
if s[left[left[t]]]>s[right[t]] then begin
rt(t);
maintain(right[t]);
maintain(t);
exit;
end;
if s[right[left[t]]]>s[right[t]] then begin
lt(left[t]);
rt(t);
maintain(left[t]);
maintain(right[t]);
maintain(t);
exit;
end;
if s[right[right[t]]]>s[left[t]] then begin
lt(t);
maintain(left[t]);
maintain(t);
exit;
end;
if s[left[right[t]]]>s[left[t]] then begin
rt(right[t]);
lt(t);
maintain(left[t]);
maintain(right[t]);
maintain(t);
exit;
end;
end;

procedure insert(var t:longint;x:longint);
begin
if t=0 then begin
inc(tot);
t:=tot;
left[t]:=0;
right[t]:=0;
value[t]:=x;
s[t]:=1;
exit;
end;
inc(s[t]);
if x<=value[t] then insert(left[t],x)
else insert(right[t],x);
maintain(t);
end;

function delete(var t:longint;x:longint):longint;
begin
dec(s[t]);
if (x=value[t]) or (x<value[t]) and (left[t]=0) or (x>value[t]) and (right[t]=0) then begin
delete:=value[t];
if (left[t]=0) or (right[t]=0) then t:=left[t]+right[t]
else
value[t]:=delete(left[t],value[t]+1);
end
else
if x<value[t] then  delete:=delete(left[t],x)
else delete:=delete(right[t],x);
end;

function pred(t,x:longint):longint;
begin
if t=0 then exit(-mm);
if value[t]=x then exit(x);
if value[t]>x then exit(pred(left[t],x))
else
exit(max(value[t],pred(right[t],x)));
end;

function succ(t,x:longint):longint;
begin
if t=0 then exit(mm);
if value[t]=x then exit(x);
if value[t]<x then exit(succ(right[t],x))
else
exit(min(value[t],succ(left[t],x)));
end;

begin
readln(n);
now:=0;
ans:=0;
t:=0;
while n>0 do begin
dec(n);
readln(i,j);
if i=0 then begin
if now>=0 then
insert(t,j)
else begin
k:=pred(t,j);
l:=succ(t,j);
if j-k<=l-j then begin
ans:=(ans+j-k)mod mmm;
delete(t,k);
end
else begin
ans:=(ans+l-j)mod mmm;
delete(t,l);
end;
end;
inc(now);
end
else begin
if now>0 then begin
k:=pred(t,j);
l:=succ(t,j);
if j-k<=l-j then begin
ans:=(ans+j-k)mod mmm;
delete(t,k);
end
else begin
ans:=(ans+l-j) mod mmm;
delete(t,l);
end;
end
else insert(t,j);
dec(now);
end;
end;
writeln(ans);
readln;
readln;
end.


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: