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

#include "bits/stdc++.h"
using namespace std;
using ld = long double;
const ld eps = 1e-9;

ld getdis(vector<ld> &l, vector<ld> &r) {
  ld sum = 0;
  for (int i = 0; i < 3; ++i) {
    sum += (l[i] - r[i]) * (l[i] - r[i]);
  }
  return sqrt(sum);
}

struct po {
  int index;
  vector<ld> coors;
  po(int _d) : coors(_d) { index = -1; }
  po(int _index, vector<ld> _coors) : index(_index), coors(_coors) {}
  po() {}
};
ld getdis(po &lpo, po &rpo) { return getdis(lpo.coors, rpo.coors); }
template <class T> class axisSorter {
  int k;

public:
  axisSorter(int _k) : k(_k) {}
  bool operator()(const T &a, const T &b) { return a.coors[k] < b.coors[k]; }
};

struct Ans {
  ld dis;
  pair<int, int> p;
};

bool operator<(const Ans &l, const Ans &r) {
  if (abs(l.dis - r.dis) < eps) {
    assert(l.p.first < l.p.second);
    assert(r.p.first < r.p.second);
    return l.p < r.p;
  } else {
    return l.dis < r.dis;
  }
  return true;
}
Ans answer;

template <class T, int Dim = 3> struct kdtree {
public:
  T midpo;
  vector<T> pos;
  shared_ptr<kdtree<T>> ltree, rtree;
  int depth;
  int axis;
  kdtree(const T &p_) : midpo(p_), ltree(), rtree() {}
  ~kdtree() {}

  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);
  }
  void getmindis() {
    vector<po> lpos, rpos;
    ld axisvalue = midpo.coors[axis];

    if (ltree != nullptr) {
      for (auto &po : ltree->pos) {
        if (axisvalue > po.coors[axis] - eps * 1000000 &&
            po.coors[axis] > axisvalue - sqrt(answer.dis) - eps * 1000000) {
          lpos.emplace_back(po);
        }
      }
    }
    if (rtree != nullptr) {
      for (auto &po : rtree->pos) {
        if (axisvalue < po.coors[axis] + eps * 1000000 &&
            po.coors[axis] < axisvalue + sqrt(answer.dis) + eps * 1000000) {
          rpos.emplace_back(po);
        }
      }
    }

    for (auto &lpo : lpos) {
      for (auto &rpo : rpos) {
        ld dis = getdis(lpo, rpo);
        pair<int, int> p(rpo.index, lpo.index);
        if (p.first > p.second)
          swap(p.first, p.second);
        Ans nans{dis, p};
        answer = min(answer, nans);
      }
      {
        ld dis = getdis(lpo, midpo);
        pair<int, int> p(midpo.index, lpo.index);
        if (p.first > p.second)
          swap(p.first, p.second);
        Ans nans{dis, p};
        answer = min(answer, nans);
      }
    }
    for (auto &rpo : rpos) {
      ld dis = getdis(midpo, rpo);
      pair<int, int> p(midpo.index, rpo.index);
      if (p.first > p.second)
        swap(p.first, p.second);
      Ans nans{dis, p};
      if (p.first == 1524 && 2763 == p.second) {
        int a = 1;
        a++;
      }
      // if (p.first == 2763 && 1524 == p.second)assert(false);
      answer = min(answer, nans);
      int b;
      b = 1;
      b++;
    }
  }

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));
    midpo = ps[mid];

    ltree = make_kdtree(ps, l, mid, depth + 1);

    rtree = make_kdtree(ps, mid + 1, r, depth + 1);
    getmindis();
    ltree.reset();
    rtree.reset();
    pos = vector<T>(ps.begin() + l, ps.begin() + r);
  }
};

//[l..r)
template <class T>
unique_ptr<kdtree<T>> make_kdtree(vector<T> &ps_, const int &l, const int &r,
                                  const int &depth = 0) {
  if (l >= r)
    return nullptr;
  else {
    return make_unique<kdtree<T>>(ps_, l, r, depth);
  }
}

vector<ld> getunit(vector<int> v) {
  vector<ld> unit;
  ld len = 0;
  for (auto a : v) {
    len += a * a;
    unit.emplace_back(ld(a));
  }
  len = sqrt(len);
  for (auto &u : unit) {
    u /= len;
  }
  return unit;
}
int gcd(int l, int r) {
  assert(l > 0 && r > 0);
  if (l > r)
    return gcd(r, l);
  else {
    const int num = r % l;
    if (num) {
      return gcd(l, num);
    } else {
      return l;
    }
  }
}
int gcd(vector<int> nums) {
  if (nums.size() == 1)
    return nums[0];
  int num = nums[0];

  for (int i = 1; i < nums.size(); ++i) {
    num = gcd(num, nums[i]);
  }
  return num;
}

int main() {
  while (1) {
    answer = Ans{1e18, make_pair(-1, -1)};
    int M, N, S, W;
    cin >> M >> N >> S >> W;
    if (!M && !N && !S && !W)
      break;
    vector<po> pos;
    vector<vector<int>> memo;
    {
      {
        int nx, ny, nz;
        for (int i = 0; i < M; ++i) {
          cin >> nx >> ny >> nz;
          memo.push_back(vector<int>{nx, ny, nz});
        }
        int g = S;
        for (int i = M; i < M + N; ++i) {
          nx = (g / 7) % 100 + 1;
          ny = (g / 700) % 100 + 1;
          nz = (g / 70000) % 100 + 1;
          memo.push_back(vector<int>{nx, ny, nz});
          if (g % 2 == 0)
            g = g / 2;
          else
            g = (g / 2) ^ W;
        }
      }
      sort(memo.begin(), memo.end(),
           [](const vector<int> &l, const vector<int> &r) {
             for (int i = 0; i < 3; ++i) {
               if (l[i] == r[i])
                 continue;
               else
                 return l[i] < r[i];
             }
             return false;
           });
      {
        vector<vector<int>> newmemo;
        map<vector<int>, int> amap;
        for (int i = 0; i < memo.size(); ++i) {
          int agcd = gcd(memo[i]);
          vector<int> v(3);
          for (int j = 0; j < 3; ++j)
            v[j] = memo[i][j] / agcd;
          if (amap.find(v) == amap.end() || amap[v] > agcd) {
            amap[v] = agcd;
          }
        }
        for (auto m : amap) {
          auto v = m.first;
          for (int i = 0; i < 3; ++i) {
            v[i] *= m.second;
          }
          newmemo.emplace_back(v);
        }
        memo = newmemo;
      }
      sort(memo.begin(), memo.end(),
           [](const vector<int> &l, const vector<int> &r) {
             for (int i = 0; i < 3; ++i) {
               if (l[i] == r[i])
                 continue;
               else
                 return l[i] < r[i];
             }
             return false;
           });
      for (int i = 0; i < memo.size(); ++i) {
        po p(i, getunit(memo[i]));
        pos.emplace_back(p);
      }
    }

    auto tree = make_kdtree(pos, 0, pos.size(), 0);
    tree->getmindis();
    auto ansp = answer;
    if (ansp.p.first > ansp.p.second)
      swap(ansp.p.first, ansp.p.second);
    for (int i = 0; i < 3; ++i) {
      cout << memo[answer.p.first][i] << " ";
    }
    for (int i = 0; i < 3; ++i) {
      cout << memo[answer.p.second][i];
      if (i == 2)
        cout << endl;
      else
        cout << " ";
    }
  }
  return 0;
}
// 1524,2763

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
using ld = long double;
const ld eps = 1e-9;

ld getdis(vector<ld> &l, vector<ld> &r) {
  ld sum = 0;
  for (int i = 0; i < 3; ++i) {
    sum += (l[i] - r[i]) * (l[i] - r[i]);
  }
  return sqrt(sum);
}

struct po {
  int index;
  vector<ld> coors;
  po(int _d) : coors(_d) { index = -1; }
  po(int _index, vector<ld> _coors) : index(_index), coors(_coors) {}
  po() {}
};
ld getdis(po &lpo, po &rpo) { return getdis(lpo.coors, rpo.coors); }
template <class T> class axisSorter {
  int k;

public:
  axisSorter(int _k) : k(_k) {}
  bool operator()(const T &a, const T &b) { return a.coors[k] < b.coors[k]; }
};

struct Ans {
  ld dis;
  pair<int, int> p;
};

bool operator<(const Ans &l, const Ans &r) {
  if (abs(l.dis - r.dis) < eps) {
    assert(l.p.first < l.p.second);
    assert(r.p.first < r.p.second);
    return l.p < r.p;
  } else {
    return l.dis < r.dis;
  }
  return true;
}
Ans answer;

template <class T, int Dim = 3> struct kdtree {
public:
  T midpo;
  vector<T> pos;
  shared_ptr<kdtree<T>> ltree, rtree;
  int depth;
  int axis;
  kdtree(const T &p_) : midpo(p_), ltree(), rtree() {}
  ~kdtree() {}

  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);
  }
  void getmindis() {
    vector<po> lpos, rpos;
    ld axisvalue = midpo.coors[axis];

    if (ltree != nullptr) {
      for (auto &po : ltree->pos) {
        if (axisvalue > po.coors[axis] - eps * 1000000 &&
            po.coors[axis] > axisvalue - sqrt(answer.dis) - eps * 1000000) {
          lpos.emplace_back(po);
        }
      }
    }
    if (rtree != nullptr) {
      for (auto &po : rtree->pos) {
        if (axisvalue < po.coors[axis] + eps * 1000000 &&
            po.coors[axis] < axisvalue + sqrt(answer.dis) + eps * 1000000) {
          rpos.emplace_back(po);
        }
      }
    }

    for (auto &lpo : lpos) {
      for (auto &rpo : rpos) {
        ld dis = getdis(lpo, rpo);
        pair<int, int> p(rpo.index, lpo.index);
        if (p.first > p.second)
          swap(p.first, p.second);
        Ans nans{dis, p};
        answer = min(answer, nans);
      }
      {
        ld dis = getdis(lpo, midpo);
        pair<int, int> p(midpo.index, lpo.index);
        if (p.first > p.second)
          swap(p.first, p.second);
        Ans nans{dis, p};
        answer = min(answer, nans);
      }
    }
    for (auto &rpo : rpos) {
      ld dis = getdis(midpo, rpo);
      pair<int, int> p(midpo.index, rpo.index);
      if (p.first > p.second)
        swap(p.first, p.second);
      Ans nans{dis, p};
      if (p.first == 1524 && 2763 == p.second) {
        int a = 1;
        a++;
      }
      // if (p.first == 2763 && 1524 == p.second)assert(false);
      answer = min(answer, nans);
      int b;
      b = 1;
      b++;
    }
  }

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));
    midpo = ps[mid];

    ltree = make_kdtree(ps, l, mid, depth + 1);

    rtree = make_kdtree(ps, mid + 1, r, depth + 1);
    getmindis();
    pos = vector<T>(ps.begin() + l, ps.begin() + r);
  }
};

//[l..r)
template <class T>
unique_ptr<kdtree<T>> make_kdtree(vector<T> &ps_, const int &l, const int &r,
                                  const int &depth = 0) {
  if (l >= r)
    return nullptr;
  else {
    return make_unique<kdtree<T>>(ps_, l, r, depth);
  }
}

vector<ld> getunit(vector<int> v) {
  vector<ld> unit;
  ld len = 0;
  for (auto a : v) {
    len += a * a;
    unit.emplace_back(ld(a));
  }
  len = sqrt(len);
  for (auto &u : unit) {
    u /= len;
  }
  return unit;
}
int gcd(int l, int r) {
  assert(l > 0 && r > 0);
  if (l > r)
    return gcd(r, l);
  else {
    const int num = r % l;
    if (num) {
      return gcd(l, num);
    } else {
      return l;
    }
  }
}
int gcd(vector<int> nums) {
  if (nums.size() == 1)
    return nums[0];
  int num = nums[0];

  for (int i = 1; i < nums.size(); ++i) {
    num = gcd(num, nums[i]);
  }
  return num;
}

int main() {
  while (1) {
    answer = Ans{1e18, make_pair(-1, -1)};
    int M, N, S, W;
    cin >> M >> N >> S >> W;
    if (!M && !N && !S && !W)
      break;
    vector<po> pos;
    vector<vector<int>> memo;
    {
      {
        int nx, ny, nz;
        for (int i = 0; i < M; ++i) {
          cin >> nx >> ny >> nz;
          memo.push_back(vector<int>{nx, ny, nz});
        }
        int g = S;
        for (int i = M; i < M + N; ++i) {
          nx = (g / 7) % 100 + 1;
          ny = (g / 700) % 100 + 1;
          nz = (g / 70000) % 100 + 1;
          memo.push_back(vector<int>{nx, ny, nz});
          if (g % 2 == 0)
            g = g / 2;
          else
            g = (g / 2) ^ W;
        }
      }
      sort(memo.begin(), memo.end(),
           [](const vector<int> &l, const vector<int> &r) {
             for (int i = 0; i < 3; ++i) {
               if (l[i] == r[i])
                 continue;
               else
                 return l[i] < r[i];
             }
             return false;
           });
      {
        vector<vector<int>> newmemo;
        map<vector<int>, int> amap;
        for (int i = 0; i < memo.size(); ++i) {
          int agcd = gcd(memo[i]);
          vector<int> v(3);
          for (int j = 0; j < 3; ++j)
            v[j] = memo[i][j] / agcd;
          if (amap.find(v) == amap.end() || amap[v] > agcd) {
            amap[v] = agcd;
          }
        }
        for (auto m : amap) {
          auto v = m.first;
          for (int i = 0; i < 3; ++i) {
            v[i] *= m.second;
          }
          newmemo.emplace_back(v);
        }
        memo = newmemo;
      }
      sort(memo.begin(), memo.end(),
           [](const vector<int> &l, const vector<int> &r) {
             for (int i = 0; i < 3; ++i) {
               if (l[i] == r[i])
                 continue;
               else
                 return l[i] < r[i];
             }
             return false;
           });
      for (int i = 0; i < memo.size(); ++i) {
        po p(i, getunit(memo[i]));
        pos.emplace_back(p);
      }
    }

    auto tree = make_kdtree(pos, 0, pos.size(), 0);
    tree->getmindis();
    auto ansp = answer;
    if (ansp.p.first > ansp.p.second)
      swap(ansp.p.first, ansp.p.second);
    for (int i = 0; i < 3; ++i) {
      cout << memo[answer.p.first][i] << " ";
    }
    for (int i = 0; i < 3; ++i) {
      cout << memo[answer.p.second][i];
      if (i == 2)
        cout << endl;
      else
        cout << " ";
    }
  }
  return 0;
}
// 1524,2763