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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define SZ(v) ((int)(v).size())
#define SQR(x) ((x) * (x))
const int maxint = -1u >> 1;
typedef long long lint;

struct P {
  int x, y;
  void input() { scanf("%d%d", &x, &y); }
  lint dist(const P &a) const {
    return SQR(lint(a.x - x)) + SQR(lint(a.y - y));
  }
};

const int maxn = 100000 + 100;
int n1, n2, r;
map<pair<int, int>, vector<P>> mm;
P p1[maxn], p2[maxn];

pair<int, int> calc_pos(const P &pt) {
  int x = pt.x / (r * 4), y = pt.y / (r * 4);
  return make_pair(x, y);
}
int main() {
  while (scanf("%d%d%d", &n1, &n2, &r) && (n1 + n2)) {
    for (int i = 0; i < n1; ++i) {
      p1[i].input();
    }
    mm.clear();
    for (int j = 0; j < n2; ++j) {
      p2[j].input();
      pair<int, int> pos = calc_pos(p2[j]);
      mm[pos].push_back(p2[j]);
    }

    lint ans = 0;
    for (int i = 0; i < n1; ++i) {
      pair<int, int> pos = calc_pos(p1[i]);
      for (int dx = -1; dx <= 1; ++dx) {
        for (int dy = -1; dy <= 1; ++dy) {
          pair<int, int> p = make_pair(pos.first + dx, pos.second + dy);
          if (mm.find(p) == mm.end())
            continue;
          const vector<P> &v = mm[p];
          for (int k = 0; k < SZ(v); ++k) {
            if (p1[i].dist(v[k]) <= SQR(4 * r)) {
              ++ans;
            }
          }
        }
      }
    }
    printf("%lld\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

/*
 * Author: NomadThanatos
 * Created Time:  2011/8/31 14:29:44
 * File Name: E.cpp
 */
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

#define out(v) cerr << #v << ": " << (v) << endl
#define SZ(v) ((int)(v).size())

const int MAXINT = -1u >> 1;
const int MAXRANGE = 10000;
const int MAXCROSS = 1000000 * 2;
const double EPS = 1e-10;

int sgn(const double &x) { return (int)((x > EPS) - (x < -EPS)); }

struct Point {
  double x, y;
  int id;
  Point(){};
  Point(const double &_x, const double &_y, const int &_id = 0)
      : x(_x), y(_y), id(_id) {}
  bool operator<(const Point &A) const {
    if (sgn(x - A.x) == 0) {
      return sgn(y - A.y) == -1;
    }
    return sgn(x - A.x) == -1;
  }
};

vector<Point> p[MAXRANGE];
vector<Point> c[MAXRANGE];
// vector<Point> work;
Point work[MAXCROSS];

void inputC() {
  int x, y;
  scanf("%d%d", &x, &y);
  c[x].push_back(Point(x, y));
};

void inputP() {
  int x, y;
  scanf("%d%d", &x, &y);
  p[x].push_back(Point(x, y));
};

int main() {
  int pnum, cnum, R;
  while (scanf("%d%d%d", &pnum, &cnum, &R) == 3) {
    int res = 0;
    R *= 3;
    if (pnum == 0 && cnum == 0)
      break;
    for (int i = 0; i < MAXRANGE; i++) {
      p[i].clear();
      c[i].clear();
    }
    for (int i = 0; i < cnum; i++) {
      inputC();
    }
    for (int i = 0; i < cnum; i++) {
      inputP();
    }
    for (int i = 0; i < MAXRANGE; i++) {
      if (SZ(p[i]) > 0) {
        // work = p[i];
        int worknum = 0;
        for (int j = 0; j < SZ(p[i]); j++) {
          work[worknum] = p[i][j];
          worknum++;
        }
        for (int j = max(0, i - R); j < min(i + R + 1, MAXRANGE); j++) {
          for (int l = 0; l < SZ(c[j]); l++) {
            // work.push_back(Point(i,c[j][l].y - sqrt(R * R - (j - i) * (j -
            // i)),1)); work.push_back(Point(i,c[j][l].y + sqrt(R * R - (j - i)
            // * (j - i)),-1));
            work[worknum] =
                Point(i, c[j][l].y - sqrt(R * R - (j - i) * (j - i)), 1);
            worknum++;
            work[worknum] =
                Point(i, c[j][l].y + sqrt(R * R - (j - i) * (j - i)), -1);
            worknum++;
          }
        }
        // sort(work.begin(),work.end());
        sort(work, work + worknum);
        int cnt = 0;
        for (int j = 0; j < worknum; j++) {
          if (work[j].id == 0) {
            res += cnt;
          } else
            cnt += work[j].id;
        }
      }
    }
    printf("%d\\n", res);
  }
  return 0;
}