首页 > 代码库 > 【BZOJ1208】宠物收养所(平衡树,splay)

【BZOJ1208】宠物收养所(平衡树,splay)

题意:见题面

思路:因为每个时刻要么全是人要么全是宠物,所以可以一棵splay解决

维护单点插入,单点删除,求前驱,求后继即可

  1 var t:array[0..100000,0..1]of longint;
  2     num,fa:array[0..100000]of longint;
  3     n,cnt,t1,t2,i,root,p,x,y:longint;
  4     ans:int64;
  5 
  6 procedure rotate(x:longint;var k:longint);
  7 var y,z,l,r:longint;
  8 begin
  9  y:=fa[x]; z:=fa[y];
 10  if t[y,0]=x then l:=0
 11   else l:=1;
 12  r:=1-l;
 13  if y=k then k:=x
 14   else
 15    if t[z,0]=y then t[z,0]:=x
 16     else t[z,1]:=x;
 17  fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y;
 18  t[y,l]:=t[x,r]; t[x,r]:=y;
 19 end;
 20 
 21 procedure splay(x:longint;var k:longint);
 22 var y,z:longint;
 23 begin
 24  while x<>k do
 25  begin
 26   y:=fa[x]; z:=fa[y];
 27   if y<>k then
 28   begin
 29    if (t[y,0]=x)xor(t[z,0]=y) then rotate(x,k)
 30     else rotate(y,k);
 31   end;
 32   rotate(x,k);
 33  end;
 34 end;
 35 
 36 procedure ins(var k:longint;x,last:longint);
 37 begin
 38  if k=0 then
 39  begin
 40   inc(cnt);
 41   k:=cnt; num[k]:=x;
 42   fa[k]:=last; splay(k,root);
 43   exit;
 44  end;
 45  if x<num[k] then ins(t[k,0],x,k)
 46   else ins(t[k,1],x,k);
 47 end;
 48 
 49 procedure del(x:longint);
 50 var k:longint;
 51 begin
 52  splay(x,root);
 53  if t[x,0]*t[x,1]=0 then root:=t[x,0]+t[x,1]
 54   else
 55   begin
 56    k:=t[x,1];
 57    while t[k,0]>0 do k:=t[k,0];
 58    t[k,0]:=t[x,0]; fa[t[x,0]]:=k;
 59    root:=t[x,1];
 60   end;
 61  fa[root]:=0;
 62 end;
 63 
 64 procedure pred(k,x:longint);
 65 begin
 66  if k=0 then exit;
 67  if num[k]<=x then
 68  begin
 69   t1:=k; pred(t[k,1],x);
 70  end
 71   else pred(t[k,0],x);
 72 end;
 73 
 74 procedure succ(k,x:longint);
 75 begin
 76  if k=0 then exit;
 77  if num[k]>=x then
 78  begin
 79   t2:=k; succ(t[k,0],x);
 80  end
 81   else succ(t[k,1],x);
 82 end;
 83 
 84 begin
 85  assign(input,bzoj1208.in); reset(input);
 86  assign(output,bzoj1208.out); rewrite(output);
 87  readln(n);
 88  for i:=1 to n do
 89  begin
 90   readln(x,y);
 91   if root=0 then begin p:=x; ins(root,y,0); end
 92    else if p=x then ins(root,y,0)
 93     else
 94     begin
 95      t1:=-1; t2:=-1;
 96      pred(root,y); succ(root,y);
 97      if t1=-1 then
 98      begin
 99       ans:=ans+num[t2]-y; ans:=ans mod 1000000; del(t2);
100      end
101       else if t2=-1 then
102       begin
103        ans:=ans+y-num[t1]; ans:=ans mod 1000000; del(t1);
104       end
105        else
106         if y-num[t1]>num[t2]-y then
107         begin
108          ans:=ans+num[t2]-y; ans:=ans mod 1000000; del(t2);
109         end
110          else
111          begin
112           ans:=ans+y-num[t1]; ans:=ans mod 1000000; del(t1);
113          end;
114     end;
115  end;
116  writeln(ans);
117  close(input);
118  close(output);
119 end.

 

【BZOJ1208】宠物收养所(平衡树,splay)