Problem p00287 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0

using namespace std;

// very very te nu ki
class Point {
public:
  double x, y;

  Point(double x = 0, double y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(a * x, a * y); }
  Point operator/(double a) { return Point(x / a, y / a); }
  Point operator*(Point a) {
    return Point(x * a.x - y * a.y, x * a.y + y * a.x);
  }

  bool operator<(const Point &p) const {
    return !equals(x, p.x) ? x < p.x : (!equals(y, p.y) && y < p.y);
  }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
  bool operator<(const Segment &s) const {
    return (p2 == s.p2) ? p1 < s.p1 : p2 < s.p2;
  }
  bool operator==(const Segment &s) const {
    return (s.p1 == p1 && s.p2 == p2) || (s.p1 == p2 && s.p2 == p1);
  }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream &operator<<(ostream &os, const Point &a) {
  os << "(" << a.x << "," << a.y << ")";
}

ostream &operator<<(ostream &os, const Segment &a) {
  os << "( " << a.p1 << " , " << a.p2 << " )";
}

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

double abs(Point a) { return sqrt(norm(a)); }

// rad ????§???????????????¢?????§?????????????????¨
Point rotate(Point a, double rad) {
  return Point(cos(rad) * a.x - sin(rad) * a.y,
               sin(rad) * a.x + cos(rad) * a.y);
}

// ??????????????¢????????????
double toRad(double agl) { return agl * M_PI / 180.0; }

// a => prev, b => cur, c=> next
// prev ?????? cur ????????£??? next ????????????????§????????±???????
double getArg(Point a, Point b, Point c) {
  double arg1 = atan2(b.y - a.y, b.x - a.x);
  double arg2 = atan2(c.y - b.y, c.x - b.x);
  double arg = fabs(arg1 - arg2);
  while (arg > M_PI)
    arg -= 2.0 * M_PI;
  return fabs(arg);
}

int ccw(Point p0, Point p1, Point p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  if (cross(a, b) > EPS)
    return COUNTER_CLOCKWISE;
  if (cross(a, b) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2 - l.p1, m.p2 - m.p1)) > EPS || // non-parallel
         abs(cross(l.p2 - l.p1, m.p1 - l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2 - l.p1, s.p1 - l.p1) * // s[0] is left of l
             cross(l.p2 - l.p1, s.p2 - l.p1) <
         EPS; // s[1] is right of l
}
bool intersectLP(Line l, Point p) {
  return abs(cross(l.p2 - p, l.p1 - p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1, s.p2, t.p1) * ccw(s.p1, s.p2, t.p2) <= 0 &&
         ccw(t.p1, t.p2, s.p1) * ccw(t.p1, t.p2, s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1 - p) + abs(s.p2 - p) - abs(s.p2 - s.p1) <
         EPS; // triangle inequality
}

Point projection(Line l, Point p) {
  double t = dot(p - l.p1, l.p1 - l.p2) / norm(l.p1 - l.p2);
  return l.p1 + (l.p1 - l.p2) * t;
}
Point reflection(Line l, Point p) { return p + (projection(l, p) - p) * 2; }
double distanceLP(Line l, Point p) { return abs(p - projection(l, p)); }
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s))
    return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t))
    return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

Point crosspoint(Line l, Line m) {
  double A = cross(l.p2 - l.p1, m.p2 - m.p1);
  double B = cross(l.p2 - l.p1, l.p2 - m.p1);
  if (abs(A) < EPS && abs(B) < EPS) {
    vector<Point> vec;
    vec.push_back(l.p1), vec.push_back(l.p2), vec.push_back(m.p1),
        vec.push_back(m.p2);
    sort(vec.begin(), vec.end());
    while (1)
      ;
    assert(vec[1] == vec[2]); //???????????°??????????????????
    return vec[1];
    // return m.p1;
  }
  if (abs(A) < EPS)
    while (1)
      ;
  return m.p1 + (m.p2 - m.p1) * (B / A);
}

//

#define MAX 3100

int H, W, M, Q;
int px[MAX], py[MAX], qx[MAX], qy[MAX];
int sx[MAX], sy[MAX], gx[MAX], gy[MAX];

bool bmap[MAX][MAX];

void veryVeryTenukiKansuu(vector<int> &X, vector<int> &Y) {
  vector<Segment> segs;
  rep(i, M) segs.push_back(Segment(Point(px[i], py[i]), Point(qx[i], qy[i])));
  rep(i, M) REP(j, i + 1, M) {
    Segment &s1 = segs[i], &s2 = segs[j];
    if ((s1.p1.x == s1.p2.x) && (s2.p1.x == s2.p2.x))
      continue;
    if ((s1.p1.y == s1.p2.y) && (s2.p1.y == s2.p2.y))
      continue;
    if (intersectSS(s1, s2)) {
      Point cp = crosspoint(s1, s2);
      X.push_back(cp.x);
      Y.push_back(cp.y);
    }
  }
}

struct Data {
  int index, w;
  bool operator<(const Data &data) const { return w > data.w; }
};

int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};

int indexMap[MAX][MAX];
int V;

vector<int> G[MAX];

void makeVVV(int nW, int nH) {
  memset(indexMap, -1, sizeof indexMap);
  rep(i, nH) rep(j, nW) if (!bmap[i][j] && indexMap[i][j] == -1) {
    indexMap[i][j] = V;
    deque<int> deq;
    deq.push_back(j + i * nW);
    while (!deq.empty()) {
      int tmp = deq.front();
      deq.pop_front();
      int x = tmp % nW, y = tmp / nW;
      rep(i, 4) {
        int nx = x + dx[i], ny = y + dy[i];
        if (!(0 <= nx && nx < nW && 0 <= ny && ny < nH))
          continue;
        if (bmap[ny][nx])
          continue;
        if (indexMap[ny][nx] != -1)
          continue;
        indexMap[ny][nx] = V;
        deq.push_back(nx + ny * nW);
      }
    }
    ++V;
  }

  /*
  rep(i,nH) {
    rep(j,nW) {
      cout << indexMap[i][j] << " ";
    }
    puts("");
  } puts("");
  */

  rep(i, nH) rep(j, nW) if (indexMap[i][j] != -1) {
    set<int> used;
    rep(k, 4) {
      int nx = j + dx[k] * 2, ny = i + dy[k] * 2;
      if (!(0 <= nx && nx < nW && 0 <= ny && ny < nH))
        continue;
      if (indexMap[ny][nx] == -1 || indexMap[ny][nx] == indexMap[i][j])
        continue;
      if (used.count(indexMap[ny][nx]))
        continue;
      used.insert(indexMap[ny][nx]);
      G[indexMap[i][j]].push_back(indexMap[ny][nx]);
    }
  }

  /*
  rep(i,V)
    {
      cout << i << "-th" << endl;
      rep(j,(int)G[i].size()) cout << G[i][j] << " "; puts("");
    }
*/
}

int mini[MAX][MAX];

void dijkstra(int s) {
  mini[s][s] = 0;
  priority_queue<Data> Q;
  Q.push((Data){s, 0});
  while (!Q.empty()) {
    Data data = Q.top();
    Q.pop();
    rep(i, (int)G[data.index].size()) {
      int next = G[data.index][i];
      if (mini[s][next] > data.w + 1) {
        mini[s][next] = data.w + 1;
        Q.push((Data){next, data.w + 1});
      }
    }
  }
}

void calc() {
  rep(i, V) rep(j, V) mini[i][j] = INT_MAX;
  rep(i, V) dijkstra(i);
}

void compute() {
  vector<int> X, Y;
  X.push_back(0), Y.push_back(0);
  X.push_back(2 * W), Y.push_back(2 * H);
  rep(i, M) {
    X.push_back(px[i]), X.push_back(qx[i]);
    Y.push_back(py[i]), Y.push_back(qy[i]);
  }
  rep(i, Q) {
    X.push_back(sx[i]), X.push_back(gx[i]);
    Y.push_back(sy[i]), Y.push_back(gy[i]);
  }

  veryVeryTenukiKansuu(X, Y);

  {
    vector<int> nX;
    rep(i, (int)X.size()) {
      nX.push_back(X[i]);
      if (X[i] - 1 >= 0)
        nX.push_back(X[i] - 1);
      if (X[i] + 1 <= 2 * W)
        nX.push_back(X[i] + 1);
    }
    X = nX;
  }
  {
    vector<int> nY;
    rep(i, (int)Y.size()) {
      nY.push_back(Y[i]);
      if (Y[i] - 1 >= 0)
        nY.push_back(Y[i] - 1);
      if (Y[i] + 1 <= 2 * H)
        nY.push_back(Y[i] + 1);
    }
    Y = nY;
  }

  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  sort(Y.begin(), Y.end());
  Y.erase(unique(Y.begin(), Y.end()), Y.end());

  map<int, int> mpX, mpY;
  rep(i, (int)X.size()) mpX[X[i]] = i;
  rep(i, (int)Y.size()) mpY[Y[i]] = i;

  px[M] = 0, py[M] = 0, qx[M] = 2 * W, qy[M] = 0;
  px[M + 1] = 2 * W, py[M + 1] = 0, qx[M + 1] = 2 * W, qy[M + 1] = 2 * H;
  px[M + 2] = 2 * W, py[M + 2] = 2 * H, qx[M + 2] = 0, qy[M + 2] = 2 * H;
  px[M + 3] = 0, py[M + 3] = 2 * H, qx[M + 3] = 0, qy[M + 3] = 0;
  rep(i, M + 4) {
    int x1 = mpX[px[i]], y1 = mpY[py[i]];
    int x2 = mpX[qx[i]], y2 = mpY[qy[i]];
    REP(y, min(y1, y2), max(y1, y2) + 1)
    REP(x, min(x1, x2), max(x1, x2) + 1) bmap[y][x] = 1;
  }

  int nH = (int)Y.size(), nW = (int)X.size();

  makeVVV(nW, nH);
  // cout << "V = " << V << endl;
  calc();

  /*
    rep(i,nH) {
      rep(j,nW) {
        cout << bmap[i][j];
      } puts("");
    }
  */
  rep(i, Q) {
    int x1 = mpX[sx[i]], y1 = mpY[sy[i]];
    int x2 = mpX[gx[i]], y2 = mpY[gy[i]];
    assert(!bmap[y1][x1]);
    assert(!bmap[y2][x2]);
    int s1 = indexMap[y1][x1];
    int s2 = indexMap[y2][x2];
    assert(s1 != -1);
    assert(s2 != -1);
    cout << mini[s1][s2] << endl;
  }
}

int main() {
  /*
  cout << 1000000000 << " " << 1000000000 << " " << 100 << endl;
  rep(i,100) {
    cout << "1 " << i*3+3 << " 999999999 " << i*3+3 << endl;
  }
  cout << 100 << endl;
  rep(i,100) {
    cout << "1 " << i*3+4 << " 999999999 " << i*3+4 << endl;
  }
  return 0;
  */
  cin >> W >> H >> M;
  rep(i, M) cin >> px[i] >> py[i] >> qx[i] >> qy[i];
  cin >> Q;
  rep(i, Q) cin >> sx[i] >> sy[i] >> gx[i] >> gy[i];
  rep(i, M) px[i] <<= 1, py[i] <<= 1, qx[i] <<= 1, qy[i] <<= 1;
  rep(i, Q) sx[i] <<= 1, sy[i] <<= 1, gx[i] <<= 1, gy[i] <<= 1;
  compute();
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0

using namespace std;

// very very te nu ki
class Point {
public:
  double x, y;

  Point(double x = 0, double y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double a) { return Point(a * x, a * y); }
  Point operator/(double a) { return Point(x / a, y / a); }
  Point operator*(Point a) {
    return Point(x * a.x - y * a.y, x * a.y + y * a.x);
  }

  bool operator<(const Point &p) const {
    return !equals(x, p.x) ? x < p.x : (!equals(y, p.y) && y < p.y);
  }

  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};

struct Segment {
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
  bool operator<(const Segment &s) const {
    return (p2 == s.p2) ? p1 < s.p1 : p2 < s.p2;
  }
  bool operator==(const Segment &s) const {
    return (s.p1 == p1 && s.p2 == p2) || (s.p1 == p2 && s.p2 == p1);
  }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream &operator<<(ostream &os, const Point &a) {
  os << "(" << a.x << "," << a.y << ")";
}

ostream &operator<<(ostream &os, const Segment &a) {
  os << "( " << a.p1 << " , " << a.p2 << " )";
}

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }

double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

double norm(Point a) { return a.x * a.x + a.y * a.y; }

double abs(Point a) { return sqrt(norm(a)); }

// rad ????§???????????????¢?????§?????????????????¨
Point rotate(Point a, double rad) {
  return Point(cos(rad) * a.x - sin(rad) * a.y,
               sin(rad) * a.x + cos(rad) * a.y);
}

// ??????????????¢????????????
double toRad(double agl) { return agl * M_PI / 180.0; }

// a => prev, b => cur, c=> next
// prev ?????? cur ????????£??? next ????????????????§????????±???????
double getArg(Point a, Point b, Point c) {
  double arg1 = atan2(b.y - a.y, b.x - a.x);
  double arg2 = atan2(c.y - b.y, c.x - b.x);
  double arg = fabs(arg1 - arg2);
  while (arg > M_PI)
    arg -= 2.0 * M_PI;
  return fabs(arg);
}

int ccw(Point p0, Point p1, Point p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  if (cross(a, b) > EPS)
    return COUNTER_CLOCKWISE;
  if (cross(a, b) < -EPS)
    return CLOCKWISE;
  if (dot(a, b) < -EPS)
    return ONLINE_BACK;
  if (norm(a) < norm(b))
    return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2 - l.p1, m.p2 - m.p1)) > EPS || // non-parallel
         abs(cross(l.p2 - l.p1, m.p1 - l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2 - l.p1, s.p1 - l.p1) * // s[0] is left of l
             cross(l.p2 - l.p1, s.p2 - l.p1) <
         EPS; // s[1] is right of l
}
bool intersectLP(Line l, Point p) {
  return abs(cross(l.p2 - p, l.p1 - p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1, s.p2, t.p1) * ccw(s.p1, s.p2, t.p2) <= 0 &&
         ccw(t.p1, t.p2, s.p1) * ccw(t.p1, t.p2, s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1 - p) + abs(s.p2 - p) - abs(s.p2 - s.p1) <
         EPS; // triangle inequality
}

Point projection(Line l, Point p) {
  double t = dot(p - l.p1, l.p1 - l.p2) / norm(l.p1 - l.p2);
  return l.p1 + (l.p1 - l.p2) * t;
}
Point reflection(Line l, Point p) { return p + (projection(l, p) - p) * 2; }
double distanceLP(Line l, Point p) { return abs(p - projection(l, p)); }
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s))
    return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t))
    return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

Point crosspoint(Line l, Line m) {
  double A = cross(l.p2 - l.p1, m.p2 - m.p1);
  double B = cross(l.p2 - l.p1, l.p2 - m.p1);
  if (abs(A) < EPS && abs(B) < EPS) {
    vector<Point> vec;
    vec.push_back(l.p1), vec.push_back(l.p2), vec.push_back(m.p1),
        vec.push_back(m.p2);
    sort(vec.begin(), vec.end());
    while (1)
      ;
    assert(vec[1] == vec[2]); //???????????°??????????????????
    return vec[1];
    // return m.p1;
  }
  if (abs(A) < EPS)
    while (1)
      ;
  return m.p1 + (m.p2 - m.p1) * (B / A);
}

//

#define MAX 3010

int H, W, M, Q;
int px[MAX], py[MAX], qx[MAX], qy[MAX];
int sx[MAX], sy[MAX], gx[MAX], gy[MAX];

bool bmap[MAX][MAX];

void veryVeryTenukiKansuu(vector<int> &X, vector<int> &Y) {
  vector<Segment> segs;
  rep(i, M) segs.push_back(Segment(Point(px[i], py[i]), Point(qx[i], qy[i])));
  rep(i, M) REP(j, i + 1, M) {
    Segment &s1 = segs[i], &s2 = segs[j];
    if ((s1.p1.x == s1.p2.x) && (s2.p1.x == s2.p2.x))
      continue;
    if ((s1.p1.y == s1.p2.y) && (s2.p1.y == s2.p2.y))
      continue;
    if (intersectSS(s1, s2)) {
      Point cp = crosspoint(s1, s2);
      X.push_back(cp.x);
      Y.push_back(cp.y);
    }
  }
}

struct Data {
  int x, y, w;
  bool operator<(const Data &data) const { return w > data.w; }
};

int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int mini[MAX][MAX];
int calc(int spx, int spy, int gpx, int gpy, int nH, int nW) {
  rep(i, nH) rep(j, nW) mini[i][j] = INT_MAX;
  mini[spy][spx] = 0;
  priority_queue<Data> Q;
  Q.push((Data){spx, spy, 0});
  while (!Q.empty()) {
    Data data = Q.top();
    Q.pop();
    int x = data.x, y = data.y;
    if (x == gpx && y == gpy)
      return mini[y][x];
    rep(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (!(0 <= nx && nx < nW && 0 <= ny && ny < nH))
        continue;
      int cost = mini[y][x] + bmap[ny][nx];
      if (mini[ny][nx] > cost) {
        mini[ny][nx] = cost;
        Q.push((Data){nx, ny, cost});
      }
    }
  }
  while (1)
    ;
}

void compute() {
  vector<int> X, Y;
  X.push_back(0), Y.push_back(0);
  X.push_back(2 * W), Y.push_back(2 * H);
  rep(i, M) {
    X.push_back(px[i]), X.push_back(qx[i]);
    Y.push_back(py[i]), Y.push_back(qy[i]);
  }
  rep(i, Q) {
    X.push_back(sx[i]), X.push_back(gx[i]);
    Y.push_back(sy[i]), Y.push_back(gy[i]);
  }

  veryVeryTenukiKansuu(X, Y);

  {
    vector<int> nX;
    rep(i, (int)X.size()) {
      nX.push_back(X[i]);
      if (X[i] - 1 >= 0)
        nX.push_back(X[i] - 1);
      if (X[i] + 1 <= 2 * W)
        nX.push_back(X[i] + 1);
    }
    X = nX;
  }
  {
    vector<int> nY;
    rep(i, (int)Y.size()) {
      nY.push_back(Y[i]);
      if (Y[i] - 1 >= 0)
        nY.push_back(Y[i] - 1);
      if (Y[i] + 1 <= 2 * H)
        nY.push_back(Y[i] + 1);
    }
    Y = nY;
  }

  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  sort(Y.begin(), Y.end());
  Y.erase(unique(Y.begin(), Y.end()), Y.end());

  map<int, int> mpX, mpY;
  rep(i, (int)X.size()) mpX[X[i]] = i;
  rep(i, (int)Y.size()) mpY[Y[i]] = i;

  px[M] = 0, py[M] = 0, qx[M] = 2 * W, qy[M] = 0;
  px[M + 1] = 2 * W, py[M + 1] = 0, qx[M + 1] = 2 * W, qy[M + 1] = 2 * H;
  px[M + 2] = 2 * W, py[M + 2] = 2 * H, qx[M + 2] = 0, qy[M + 2] = 2 * H;
  px[M + 3] = 0, py[M + 3] = 2 * H, qx[M + 3] = 0, qy[M + 3] = 0;
  rep(i, M + 4) {
    int x1 = mpX[px[i]], y1 = mpY[py[i]];
    int x2 = mpX[qx[i]], y2 = mpY[qy[i]];
    REP(y, min(y1, y2), max(y1, y2) + 1)
    REP(x, min(x1, x2), max(x1, x2) + 1) bmap[y][x] = 1;
  }

  int nH = (int)Y.size(), nW = (int)X.size();
  /*
  rep(i,nH) {
    rep(j,nW) {
      cout << bmap[i][j];
    } puts("");
  }
  */
  rep(i, Q) {
    int x1 = mpX[sx[i]], y1 = mpY[sy[i]];
    int x2 = mpX[gx[i]], y2 = mpY[gy[i]];
    assert(!bmap[y1][x1]);
    assert(!bmap[y2][x2]);
    cout << calc(x1, y1, x2, y2, nH, nW) << endl;
  }
}

int main() {
  /*
  cout << 1000000000 << " " << 1000000000 << " " << 100 << endl;
  rep(i,100) {
    cout << "1 " << i*3+3 << " 999999999 " << i*3+3 << endl;
  }
  cout << 100 << endl;
  rep(i,100) {
    cout << "1 " << i*3+4 << " 999999999 " << i*3+4 << endl;
  }
  return 0;
  */
  cin >> W >> H >> M;
  rep(i, M) cin >> px[i] >> py[i] >> qx[i] >> qy[i];
  cin >> Q;
  rep(i, Q) cin >> sx[i] >> sy[i] >> gx[i] >> gy[i];
  rep(i, M) px[i] <<= 1, py[i] <<= 1, qx[i] <<= 1, qy[i] <<= 1;
  rep(i, Q) sx[i] <<= 1, sy[i] <<= 1, gx[i] <<= 1, gy[i] <<= 1;
  compute();
  return 0;
}