bzoj1208: [HNOI2004]宠物收养所 (sbt)
切傻逼题还能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.
因疲惫而轻易入眠,是对自己一天努力的最好褒奖。 要和泪子一起努力怀抱梦想对抗残酷的现实……