Problem p02303 (C++) — buggy submission, verdict: Memory Limit Exceeded

// http://ir5.hatenablog.com/entry/20131221/1387557630
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <utility>
#include <vector>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
typedef pair<double, double> P;
typedef pair<int, int> IP;
double norm(P a, P b) {
  double x = a.first - b.first;
  double y = a.second - b.second;
  return sqrt(x * x + y * y);
}
int main() {
  int N;
  cin >> N;
  vector<P> p(N);
  REP(i, N) {
    double x, y;
    cin >> x >> y;
    p[i] = make_pair(x, y);
  }
  double xmin = p[0].first, ymin = p[0].second;
  REP(i, N) {
    xmin = min(xmin, p[i].first);
    ymin = min(ymin, p[i].second);
  }
  REP(i, N) {
    p[i].first -= xmin;
    p[i].second -= ymin;
  }
  // std::rand is often used.
  random_shuffle(p.begin(), p.end());
  double delta = norm(p[0], p[1]);
  multimap<IP, int> S;
  S.insert(make_pair(IP(p[0].first / delta, p[0].second / delta), 0));
  S.insert(make_pair(IP(p[1].first / delta, p[1].second / delta), 1));
  for (int i = 2; i < N; ++i) {
    IP ip(p[i].first / delta, p[i].second / delta);
    bool update = false;
    for (int dx = -1; dx <= 1; ++dx)
      for (int dy = -1; dy <= 1; ++dy) {
        int count = S.count(IP(ip.first + dx, ip.second + dy));
        auto it = S.find(IP(ip.first + dx, ip.second + dy));
        for (int j = 0; j < count; ++j) {
          double d2 = norm(p[i], p[it->second]);
          if (delta > d2) {
            delta = d2;
            update = true;
          }
          ++it;
        }
      }
    if (update) {
      S.clear();
      for (int j = 0; j <= i; ++j) {
        S.insert(make_pair(IP(p[j].first / delta, p[j].second / delta), j));
      }
    } else {
      S.insert(make_pair(ip, i));
    }
  }
  cout.setf(ios::fixed);
  cout.precision(6);
  cout << delta << endl;
}

Error: MLE

Fixed submission:

// http://ir5.hatenablog.com/entry/20131221/1387557630
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
typedef pair<double, double> P;
typedef pair<int, int> IP;
double norm(P a, P b) {
  double x = a.first - b.first;
  double y = a.second - b.second;
  return sqrt(x * x + y * y);
}
// http://stackoverflow.com/questions/20590656/
struct pairhash {
public:
  template <typename T, typename U>
  std::size_t operator()(const std::pair<T, U> &x) const {
    return (std::hash<T>()(x.first) << 32LL) ^ std::hash<U>()(x.second);
  }
};
int main() {
  int N;
  cin >> N;
  vector<P> p(N);
  REP(i, N) {
    double x, y;
    cin >> x >> y;
    p[i] = make_pair(x, y);
  }
  double xmin = p[0].first, ymin = p[0].second;
  REP(i, N) {
    xmin = min(xmin, p[i].first);
    ymin = min(ymin, p[i].second);
  }
  REP(i, N) {
    p[i].first -= xmin;
    p[i].second -= ymin;
  }
  // std::rand is often used.
  random_shuffle(p.begin(), p.end());
  double delta = norm(p[0], p[1]);
  unordered_map<IP, vector<int>, pairhash> S;
  S[IP(p[0].first / delta, p[0].second / delta)].push_back(0);
  S[IP(p[1].first / delta, p[1].second / delta)].push_back(1);
  for (int i = 2; i < N; ++i) {
    IP ip(p[i].first / delta, p[i].second / delta);
    bool update = false;
    for (int dx = -1; dx <= 1; ++dx)
      for (int dy = -1; dy <= 1; ++dy) {
        for (int j : S[IP(ip.first + dx, ip.second + dy)]) {
          double d2 = norm(p[i], p[j]);
          if (delta > d2) {
            delta = d2;
            update = true;
          }
        }
      }
    if (update) {
      S.clear();
      for (int j = 0; j <= i; ++j) {
        S[IP(p[j].first / delta, p[j].second / delta)].push_back(j);
      }
    } else {
      S[ip].push_back(i);
    }
  }
  cout.setf(ios::fixed);
  cout.precision(6);
  cout << delta << endl;
}