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

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

struct P {
  int64_t x;
  int64_t y;
  int64_t p;
};

int64_t ans[16];

struct VA {
  int64_t v[16];
};

unordered_map<int64_t, VA> xl_memo;
unordered_map<int64_t, VA> yl_memo;

void eval(vector<P> &ps, vector<int> &ss, int n) {
  int c = 0;
  int64_t xs = 0;
  int64_t ys = 0;
  FOR_LT(i, 0, n) {
    if (ss[i] == 1) {
      xs += (1 << i);
      c++;
    } else if (ss[i] == 2) {
      ys += (1 << i);
      c++;
    }
  }

  auto xit = xl_memo.find(xs);
  if (xit == xl_memo.end()) {
    VA va = {0};
    set<int64_t> xl = {0};
    FOR_LT(i, 0, n) {
      if (ss[i] == 1) {
        xl.insert(ps[i].y);
      }
    }

    FOR_LT(i, 0, n) {
      int64_t val = INT_MAX;
      auto it = xl.lower_bound(ps[i].y);
      if (it != xl.end()) {
        val = min(val, abs(*it - ps[i].y));
      }
      if (it != xl.begin()) {
        it--;
        val = min(val, abs(*it - ps[i].y));
      }
      va.v[i] = val;
    }

    xit = xl_memo.insert({xs, va}).first;
  }

  auto yit = yl_memo.find(ys);
  if (yit == yl_memo.end()) {
    VA va = {0};
    set<int64_t> yl = {0};
    FOR_LT(i, 0, n) {
      if (ss[i] == 2) {
        yl.insert(ps[i].x);
      }
    }

    FOR_LT(i, 0, n) {
      int64_t val = INT_MAX;
      auto it = yl.lower_bound(ps[i].x);
      if (it != yl.end()) {
        val = min(val, abs(*it - ps[i].x));
      }
      if (it != yl.begin()) {
        it--;
        val = min(val, abs(*it - ps[i].x));
      }
      va.v[i] = val;
    }

    yit = yl_memo.insert({ys, va}).first;
  }

  int64_t sum = 0;
  FOR_LT(i, 0, n) {
    int64_t cs = INT64_MAX;
    { cs = min(cs, xit->second.v[i] * ps[i].p); }
    { cs = min(cs, yit->second.v[i] * ps[i].p); }
    sum += cs;
  }
  ans[c] = min(ans[c], sum);
}

void sel(vector<P> &ps, vector<int> &ss, int i, int n) {
  if (i == n) {
    eval(ps, ss, n);
    return;
  }
  FOR_LT(j, 0, 3) {
    ss[i] = j;
    sel(ps, ss, i + 1, n);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;

  vector<P> ps(n);
  FOR_LT(i, 0, n) {
    auto &p = ps[i];
    cin >> p.x >> p.y >> p.p;
  }

  vector<int> ss(n);

  FOR_LE(i, 0, n) { ans[i] = INT64_MAX; }

  sel(ps, ss, 0, n);

  FOR_LE(i, 0, n) { cout << ans[i] << endl; }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define FOR_LT(i, beg, end) for (int i = (int)(beg); i < (int)(end); i++)
#define FOR_LE(i, beg, end) for (int i = (int)(beg); i <= (int)(end); i++)
#define FOR_DW(i, beg, end) for (int i = (int)(beg); (int)(end) <= i; i--)
#define REP(n) for (int repeat_index = 0; repeat_index < (int)n; repeat_index++)

using namespace std;

struct P {
  int64_t x;
  int64_t y;
  int64_t p;
};

int64_t ans[16];

unordered_map<int64_t, int64_t> xl_memo;
unordered_map<int64_t, int64_t> yl_memo;

void eval(vector<P> &ps, vector<int> &ss, int n) {
  vector<int64_t> xl = {0};
  vector<int64_t> yl = {0};
  int c = 0;
  int64_t xs = 0;
  int64_t ys = 0;
  FOR_LT(i, 0, n) {
    if (ss[i] == 1) {
      xl.push_back(ps[i].y);
      xs += (1 << i);
      c++;
    } else if (ss[i] == 2) {
      yl.push_back(ps[i].x);
      ys += (1 << i);
      c++;
    }
  }

  int64_t sum = 0;
  FOR_LT(i, 0, n) {
    int64_t cs = INT64_MAX;
    {
      int64_t idx = (i << 16) + xs;
      auto it = xl_memo.find(idx);
      if (it == xl_memo.end()) {
        int64_t minv = INT64_MAX;
        for (auto y : xl) {
          minv = min(minv, abs(y - ps[i].y));
        }
        it = xl_memo.insert({idx, minv}).first;
      }
      cs = min(cs, it->second * ps[i].p);
    }
    {
      int64_t idx = (i << 16) + ys;
      auto it = yl_memo.find(idx);
      if (it == yl_memo.end()) {
        int64_t minv = INT64_MAX;
        for (auto x : yl) {
          minv = min(minv, abs(x - ps[i].x));
        }
        it = yl_memo.insert({idx, minv}).first;
      }
      cs = min(cs, it->second * ps[i].p);
    }
    sum += cs;
  }
  ans[c] = min(ans[c], sum);
}

void sel(vector<P> &ps, vector<int> &ss, int i, int n) {
  if (i == n) {
    eval(ps, ss, n);
    return;
  }
  FOR_LT(j, 0, 3) {
    ss[i] = j;
    sel(ps, ss, i + 1, n);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout << fixed << setprecision(20);

  int n;
  cin >> n;

  vector<P> ps(n);
  FOR_LT(i, 0, n) {
    auto &p = ps[i];
    cin >> p.x >> p.y >> p.p;
  }

  vector<int> ss(n);

  FOR_LE(i, 0, n) { ans[i] = INT64_MAX; }

  sel(ps, ss, 0, n);

  FOR_LE(i, 0, n) { cout << ans[i] << endl; }

  return 0;
}