[BZOJ1208] [HNOI2004]宠物收养所

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1208

题目大意

。。

题解

模板题

const
 maxn=100005;
var
 w:array[1..2,-1..maxn,1..6]of longint;
 sum,root:array[1..2]of longint;
 i,j,k:longint;
 n,a,b:longint;
 ans,c,d:int64;
procedure print(key,a:longint);
begin
 if w[key,a,1]<>-1 then print(key,w[key,a,1]);
 write(w[key,a,6],' ');
 if w[key,a,2]<>-1 then print(key,w[key,a,2]);
 if a=root[key] then writeln;
end;

procedure rotate(key,a,kind:longint);
var b,unkind:longint;
begin
 b:=w[key,a,3]; unkind:=kind xor 3;
 w[key,a,4]:=w[key,b,4]; dec(w[key,b,4],w[key,a,5]+w[key,w[key,a,kind],4]);
 w[key,w[key,a,unkind],3]:=b; w[key,b,kind]:=w[key,a,unkind];
 w[key,a,unkind]:=b; w[key,a,3]:=w[key,b,3]; w[key,b,3]:=a;
 if w[key,a,3]<>-1
 then
  if w[key,w[key,a,3],1]=b
  then w[key,w[key,a,3],1]:=a
  else w[key,w[key,a,3],2]:=a;
end;

procedure splay(key,a,goal:longint);
var b,kind,unkind:longint;
begin
 while w[key,a,3]<>goal do
  begin
   b:=w[key,a,3]; if w[key,b,1]=a then kind:=1 else kind:=2; unkind:=kind xor 3;
   if w[key,b,3]=goal then rotate(key,a,kind)
   else
    if w[key,w[key,b,3],kind]=b
    then begin rotate(key,b,kind); rotate(key,a,kind); end
    else begin rotate(key,a,kind); rotate(key,a,unkind); end
  end;
 if goal=-1 then root[key]:=a;
end;

procedure init(key,a:longint);
var tt,fa,kind:longint;
begin
 tt:=root[key];
 while tt<>-1 do
  begin
   inc(w[key,tt,4]); fa:=tt;
   if w[key,tt,6]=a then break;
   if a<w[key,tt,6]
   then begin tt:=w[key,tt,1]; kind:=1; end
   else begin tt:=w[key,tt,2]; kind:=2; end;
  end;
 if tt<>-1
 then begin inc(w[key,tt,5]); splay(key,tt,-1); end
 else begin inc(sum[key]); w[key,sum[key],1]:=-1; w[key,sum[key],2]:=-1; w[key,sum[key],3]:=fa; w[key,sum[key],4]:=1; w[key,sum[key],5]:=1; w[key,sum[key],6]:=a; w[key,fa,kind]:=sum[key]; splay(key,sum[key],-1); end;
end;

function getmax(key,a:longint):longint;
var tt:longint;
begin
 tt:=a;
 while w[key,tt,2]<>-1 do
  tt:=w[key,tt,2];
 exit(tt);
end;

function getmin(key,a:longint):longint;
var tt:longint;
begin
 tt:=a;
 while w[key,tt,1]<>-1 do
  tt:=w[key,tt,1];
 exit(tt);
end;

procedure del(key,a:longint);
var tt:longint;
begin
 tt:=root[key];
 while w[key,tt,6]<>a do
  if a<w[key,tt,6]
  then tt:=w[key,tt,1]
  else tt:=w[key,tt,2];
 splay(key,tt,-1);
 if w[key,tt,5]=1
 then begin
  splay(key,getmax(key,w[key,root[key],1]),root[key]);
  w[key,w[key,root[key],1],2]:=w[key,root[key],2];
  root[key]:=w[key,root[key],1];
  w[key,root[key],3]:=-1;
  w[key,w[key,root[key],2],3]:=root[key];
  inc(w[key,root[key],4],w[key,w[key,root[key],2],4]);end
 else begin dec(w[key,tt,4]); dec(w[key,tt,5]); end;
end;

begin
 readln(n); ans:=0;
 root[1]:=1; sum[1]:=1;
 w[1,1,1]:=-1; w[1,1,2]:=-1; w[1,1,3]:=-1; w[1,1,4]:=1; w[1,1,5]:=1; w[1,1,6]:=-1000000000;
 root[2]:=1; sum[2]:=1;
 w[2,1,1]:=-1; w[2,1,2]:=-1; w[2,1,3]:=-1; w[2,1,4]:=1; w[2,1,5]:=1; w[2,1,6]:=-1000000000;
 for i:=1 to n do
  begin
   readln(a,b);
   if a=0
   then begin
        if w[2,root[2],4]>=2
        then begin
            init(2,b);
            if w[2,root[2],5]>=3
            then del(2,b)
            else begin
                c:=100000000000; d:=100000000000;
                if w[2,w[2,root[2],1],4]>=2
                then c:=w[2,getmax(2,w[2,root[2],1]),6];
                if w[2,w[2,root[2],2],4]>=1
                then d:=w[2,getmin(2,w[2,root[2],2]),6];
                if abs(c-b)<=abs(d-b)
                then begin ans:=(ans+abs(c-b))mod 1000000; del(2,c); end
                else begin ans:=(ans+abs(d-b))mod 1000000; del(2,d); end;
                del(2,b);
            end;
        end
        else init(1,b);
   end
   else begin
        if w[1,root[1],4]>=2
        then begin
            init(1,b);
            if w[1,root[1],5]>=3
            then del(1,b)
            else begin
                c:=100000000000; d:=100000000000;
                if w[1,w[1,root[1],1],4]>=2
                then c:=w[1,getmax(1,w[1,root[1],1]),6];
                if w[1,w[1,root[1],2],4]>=1
                                then d:=w[1,getmin(1,w[1,root[1],2]),6];
                if abs(c-b)<=abs(d-b)
                then begin ans:=(ans+abs(c-b))mod 1000000; del(1,c); end
                else begin ans:=(ans+abs(d-b))mod 1000000; del(1,d); end;
                del(1,b);
            end;
        end
        else init(2,b);
   end;
  end;
 writeln(ans);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值