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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i, a) for (auto &i : a)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define RFOR(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; i--)
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define ALL(a) (a).begin(), (a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  EACH(x, vec) is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, vector<vector<T>> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

struct po {
  short index;
  short coors[2];
  po() : index(-1) {}
};
template <class T> class AxisSorter {
  short k;

public:
  AxisSorter(short _k) : k(_k) {}
  bool operator()(const T &a, const T &b) { return a.coors[k] < b.coors[k]; }
};
ll getdis(const po &l, const po &r) {
  ll dis = 0;
  REP(i, 2) {
    dis += (ll)(l.coors[i] - r.coors[i]) * (l.coors[i] - r.coors[i]);
  }
  assert(dis >= 0);
  return dis;
}
template <class T, short Dim = 2> class KDTree {
public:
  T val;
  KDTree<T> *ltree, *rtree;
  short depth;
  short axis;
  KDTree(const T &p_) : val(p_), ltree(nullptr), rtree(nullptr) {}
  KDTree(vector<T> &ps_, const int &l, const int &r, const int depth_ = 0)
      : ltree(nullptr), rtree(nullptr), depth(depth_), axis(depth % Dim) {
    init(ps_, l, r);
  }
  ~KDTree() {
    if (ltree != nullptr)
      delete ltree;
    if (rtree != nullptr)
      delete rtree;
  }
  vector<T> query(const T &amin, const T &amax) {
    vector<T> ans;
    bool aok = true;
    for (short i = 0; i < Dim; ++i) {
      if (amin.coors[i] <= val.coors[i] && val.coors[i] <= amax.coors[i]) {
      } else {
        aok = false;
        break;
      }
    }
    if (aok) {
      ans.emplace_back(val);
    }
    AxisSorter<T> as(axis);
    if (as(val, amax) || val.coors[axis] == amax.coors[axis]) {
      if (rtree != nullptr) {
        vector<T> tans(rtree->query(amin, amax));
        ans.insert(ans.end(), tans.begin(), tans.end());
      }
    }
    if (as(amin, val) || val.coors[axis] == amin.coors[axis]) {
      if (ltree != nullptr) {
        vector<T> tans(ltree->query(amin, amax));
        ans.insert(ans.end(), tans.begin(), tans.end());
      }
    }
    return ans;
  }
  ll get_closest(const T &apo) {
    ll res = getdis(apo, val);
    if (res == 0)
      res = linf;
    AxisSorter<T> as(axis);
    if (as(apo, val) || val.coors[axis] == apo.coors[axis]) {
      if (ltree)
        res = min(res, ltree->get_closest(apo));
      ll dis = apo.coors[axis] - val.coors[axis];
      if (dis * dis >= res)
        return res;
      else {
        if (rtree)
          res = min(res, rtree->get_closest(apo));
      }
    } else {
      if (rtree)
        res = min(res, rtree->get_closest(apo));
      ll dis = val.coors[axis] - apo.coors[axis];
      if (dis * dis >= res)
        return res;
      else {
        if (ltree)
          res = min(res, ltree->get_closest(apo));
      }
    }
    return res;
  }

private:
  void init(vector<T> &ps, const int &l, const int &r) {
    if (l >= r) {
      return;
    }
    const int mid = (l + r) / 2;
    nth_element(ps.begin() + l, ps.begin() + mid, ps.begin() + r,
                AxisSorter<T>(axis));
    val = ps[mid];
    ltree = make_kdtree(ps, l, mid, depth + 1);
    rtree = make_kdtree(ps, mid + 1, r, depth + 1);
  }
};
//[l..r)
template <class T>
KDTree<T> *make_kdtree(vector<T> &ps_, const int &l, const int &r,
                       const int &depth = 0) {
  if (l >= r)
    return nullptr;
  else {
    return new KDTree<T>(ps_, l, r, depth);
  }
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  ll n;
  cin >> n;
  vector<po> v(n, po());
  REP(i, n) { cin >> v[i].coors[0] >> v[i].coors[1]; }
  KDTree<po> *kdtree = make_kdtree(v, 0, n);
  ll ans = linf;
  REP(i, n) { ans = min(ans, kdtree->get_closest(v[i])); }
  cout << fixed << setprecision(10) << ans << endl;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i, a) for (auto &i : a)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define RFOR(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; i--)
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define ALL(a) (a).begin(), (a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  EACH(x, vec) is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, vector<vector<T>> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

struct po {
  short index;
  vector<short> coors;
  po(short _d) : coors(_d) { index = -1; }
  po() {}
};
template <class T> class AxisSorter {
  short k;

public:
  AxisSorter(short _k) : k(_k) {}
  bool operator()(const T &a, const T &b) { return a.coors[k] < b.coors[k]; }
};
ll getdis(const po &l, const po &r) {
  ll dis = 0;
  REP(i, l.coors.size()) {
    dis += (ll)(l.coors[i] - r.coors[i]) * (l.coors[i] - r.coors[i]);
  }
  assert(dis >= 0);
  return dis;
}
template <class T, short Dim = 2> class KDTree {
public:
  T val;
  KDTree<T> *ltree, *rtree;
  short depth;
  short axis;
  KDTree(const T &p_) : val(p_), ltree(nullptr), rtree(nullptr) {}
  KDTree(vector<T> &ps_, const int &l, const int &r, const int depth_ = 0)
      : ltree(nullptr), rtree(nullptr), depth(depth_), axis(depth % Dim) {
    init(ps_, l, r);
  }
  ~KDTree() {
    if (ltree != nullptr)
      delete ltree;
    if (rtree != nullptr)
      delete rtree;
  }
  vector<T> query(const T &amin, const T &amax) {
    vector<T> ans;
    bool aok = true;
    for (short i = 0; i < Dim; ++i) {
      if (amin.coors[i] <= val.coors[i] && val.coors[i] <= amax.coors[i]) {
      } else {
        aok = false;
        break;
      }
    }
    if (aok) {
      ans.emplace_back(val);
    }
    AxisSorter<T> as(axis);
    if (as(val, amax) || val.coors[axis] == amax.coors[axis]) {
      if (rtree != nullptr) {
        vector<T> tans(rtree->query(amin, amax));
        ans.insert(ans.end(), tans.begin(), tans.end());
      }
    }
    if (as(amin, val) || val.coors[axis] == amin.coors[axis]) {
      if (ltree != nullptr) {
        vector<T> tans(ltree->query(amin, amax));
        ans.insert(ans.end(), tans.begin(), tans.end());
      }
    }
    return ans;
  }
  ll get_closest(const T &apo) {
    ll res = getdis(apo, val);
    if (res == 0)
      res = linf;
    AxisSorter<T> as(axis);
    if (as(apo, val) || val.coors[axis] == apo.coors[axis]) {
      if (ltree)
        res = min(res, ltree->get_closest(apo));
      ll dis = apo.coors[axis] - val.coors[axis];
      if (dis * dis >= res)
        return res;
      else {
        if (rtree)
          res = min(res, rtree->get_closest(apo));
      }
    } else {
      if (rtree)
        res = min(res, rtree->get_closest(apo));
      ll dis = val.coors[axis] - apo.coors[axis];
      if (dis * dis >= res)
        return res;
      else {
        if (ltree)
          res = min(res, ltree->get_closest(apo));
      }
    }
    return res;
  }

private:
  void init(vector<T> &ps, const int &l, const int &r) {
    if (l >= r) {
      return;
    }
    const int mid = (l + r) / 2;
    nth_element(ps.begin() + l, ps.begin() + mid, ps.begin() + r,
                AxisSorter<T>(axis));
    val = ps[mid];
    ltree = make_kdtree(ps, l, mid, depth + 1);
    rtree = make_kdtree(ps, mid + 1, r, depth + 1);
  }
};
//[l..r)
template <class T>
KDTree<T> *make_kdtree(vector<T> &ps_, const int &l, const int &r,
                       const int &depth = 0) {
  if (l >= r)
    return nullptr;
  else {
    return new KDTree<T>(ps_, l, r, depth);
  }
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  ll n;
  cin >> n;
  vector<po> v(n, po(2));
  REP(i, n) { cin >> v[i].coors[0] >> v[i].coors[1]; }
  KDTree<po> *kdtree = make_kdtree(v, 0, n);
  ll ans = linf;
  REP(i, n) { ans = min(ans, kdtree->get_closest(v[i])); }
  cout << fixed << setprecision(10) << ans << endl;
}