Cod sursa(job #401700)

Utilizator hungntnktpHungntnktp hungntnktp Data 23 februarie 2010 05:32:26
Problema Gropi Scor 40
Compilator fpc Status done
Runda Arhiva de probleme Marime 3.57 kb
{FP}
{$M 64000000,0}
{$MODE OBJFPC}
{$IFDEF ANHDQ}
  {$INLINE OFF}
  {$H-,I+,Q+,R+,S+}
{$ELSE}
  {$INLINE ON}
  {$H+,I-,Q-,R-,S-}
{$ENDIF}

// Result:
program gropi_AnhDQ;

const
  FI_NAME = 'gropi.in';
  FO_NAME = 'gropi.out';
  MaxN    = 100111;
  MaxQ    = 100111;

type
  Black = record
            x, y: LongInt;
          end;

  Query = record
            x, y, u, v: LongInt;
          end;

var
  Fi, Fo: Text;
  n, m  : LongInt;
  B     : array[1..MaxN] of Black;
  Q     : array[1..MaxQ] of Query;
  S     : array[1..MaxN] of LongInt;
(*------------------------------*)
  procedure Swap(var li1, li2: LongInt); inline;
  var li: LongInt;
  begin
    li := li1; li1 := li2; li2 := li;
  end;
(*------------------------------*)
  procedure Swap(var b1, b2: Black); inline;
  var b: Black;
  begin
    b := b1; b1 := b2; b2 := b;
  end;
(*------------------------------*)
  procedure ReadIn();
  var i: LongInt;
  begin
    Assign(Fi, FI_NAME);
    Reset(Fi);
    read(Fi, n, n);
    for i := 1 to n do
      with B[i] do
      begin
        read(Fi, x, y);
        x := 3 - x;
      end;
    read(Fi, m);
    for i := 1 to m do
      with Q[i] do
      begin
        read(Fi, x, y, u, v);
        if y > v then
        begin
          Swap(x, u);
          Swap(y, v);
        end;
      end;
    Close(Fi);
  end;
(*------------------------------*)
  procedure QSort(lo, hi: LongInt); inline;
  var i, j, key: LongInt;
  begin
    i := lo; j := hi;
    key := B[lo + Random(hi - lo + 1)].y;

    repeat
      while B[i].y < key do Inc(i);
      while key < B[j].y do Dec(j);

      if i <= j then
      begin
        if i < j then Swap(B[i], B[j]);
        Inc(i); Dec(j);
      end;
    until i > j;

    if lo < j then QSort(lo, j);
    if i < hi then QSort(i, hi);
  end;
(*------------------------------*)
  procedure Init();
  var i: LongInt;
  begin
    QSort(1, n);
    for i := 2 to n do
      with B[i] do
        S[i] := S[i - 1] + (y - B[i - 1].y) + Abs(x - B[i - 1].x);
  end;
(*------------------------------*)
  function FindL(y: LongInt): LongInt; inline;
  var lo, hi, mid: LongInt;
  begin
    result := 0;
    lo := 1; hi := n;
    while lo <= hi do
    begin
      mid := (lo + hi) shr 1;
      if B[mid].y <= y then
      begin
        result := mid;
        lo := mid + 1;
      end
      else hi := mid - 1;
    end;
  end;
(*------------------------------*)
  function FindR(y: LongInt): LongInt; inline;
  var lo, hi, mid: LongInt;
  begin
    result := 0;
    lo := 1; hi := n;
    while lo <= hi do
    begin
      mid := (lo + hi) shr 1;
      if B[mid].y >= y then
      begin
        result := mid;
        hi := mid - 1;
      end
      else lo := mid + 1;
    end;
  end;
(*------------------------------*)
  procedure Process();
  var i, jl, jr, res: LongInt;
  begin
    Assign(Fo, FO_NAME);
    Rewrite(Fo);

    for i := 1 to m do
      with Q[i] do
      begin
        if y = v then res := Abs(u - x) + 1
        else
        begin
          jr := FindR(y);
          if (jr = 0) or (jr > v) then res := (v - y) + Abs(u - x)
          else
          begin
            res := (B[jr].y - y) + Abs(B[jr].x - x);
            jl := FindL(v);
            Inc(res, (v - B[jl].y) + Abs(u - B[jl].x));
            Inc(res, S[jl] - S[jr]);
            Inc(res);
          end;
        end;
        WriteLn(Fo, res);
      end;

    Close(Fo);
  end;
(*------------------------------*)
begin
  Randomize();
  ReadIn();
  Init();
  Process();
end.