Cod sursa(job #401697)

Utilizator hungntnktpHungntnktp hungntnktp Data 23 februarie 2010 05:24:26
Problema Gropi Scor 20
Compilator fpc Status done
Runda Arhiva de probleme Marime 2.55 kb
{$M 64000000,0}
{$INLINE ON}
{$H-,I+,Q+,R+,S+}
Const
  InputFile  = 'gropi.in';
  OutputFile = 'gropi.out';
  MaxN = 111111;
  oo = 2000000009;
Type
  Arr1Lint = array[0..MaxN] of Int64;
Var
  x, y, Sum : Arr1Lint;
  n, C, tests, Res : Int64;
  x1, x2, y1, y2 : Int64;

  Procedure Enter;
  Var
    i : LongInt;
  Begin
    Read(C, n);
    For i := 1 to n do Read(x[i], y[i]);
  End;

  Procedure Swap(Var x, y : Int64);inline;
  Var
    Temp : Int64;
  Begin
    Temp := x; x := y; y := Temp;
  End;

  Procedure Sort(L, H : LongInt);inline;
  Var
    i, j, key : LongInt;
  Begin
    If L >= H then Exit;
    i := L; j := H;
    key := y[L + Random(H - L + 1)];
    Repeat
      While y[i] < key do Inc(i);
      While y[j] > key do Dec(j);
      If i <= j then
        Begin
          If i < j then
            Begin
              Swap(x[i], x[j]);
              Swap(y[i], y[j]);
            End;
          Inc(i); Dec(j);
        End;
    Until i > j;
    Sort(L, j); Sort(i, H);
  End;

  Procedure Init;
  Var
    i : LongInt;
  Begin
    Sort(1, n);
    Sum[1] := 0; y[0] := 0; y[n + 1] := oo;
    For i := 2 to n do
      Sum[i] := Sum[i - 1] + Abs(x[i] - x[i - 1]) + Abs(y[i] - y[i - 1]);
  End;

  Function Search(key : LongInt) : LongInt;inline;
  Var
    inf, sup, median, kk : LongInt;
  Begin
    inf := 0; sup := n + 1;
    While inf <= sup do
      Begin
        median := (inf + sup) div 2;
        If y[median] < key then
          Begin
            kk := median;
            inf := median + 1;
          End
        Else sup := median - 1;
      End;
    Search := kk;
  End;

  Function Kc(u1, v1, u2, v2 : LongInt) : Int64;inline;
  Begin
    If u1 = u2 then Kc := Abs(u1 - u2) + Abs(v1 - v2) + 1
    Else Kc := Abs(u1 - u2) + Abs(v1 - v2) - 1;
  End;

  Procedure Process;
  Var
    vt1, vt2, c1, c2 : Int64;
  Begin
    If y1 > y2 then
      Begin
        Swap(x1, x2);
        Swap(y1, y2);
      End;
    vt1 := Search(y1) + 1;
    vt2 := Search(y2);
    c1 := Kc(x1, y1, x[vt1], y[vt1]);
    c2 := Kc(x[vt2], y[vt2], x2, y2);
    Res := c1 + c2 + Sum[vt2] - Sum[vt1] + 1;
  End;

Begin
  Assign(Input, InputFile); Reset(Input);
  Assign(Output, OutputFile); Rewrite(Output);
  Enter;
  Init;
  Read(tests);
  While tests > 0 do
    Begin
      Read(x1, y1, x2, y2);
      If (x1 = x2) and (y1 = y2) then Writeln('1')
      Else
        Begin
          Process;
          Writeln(Res);
        End;
      Dec(tests);
    End;
  Close(Input); Close(Output);
End.