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

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

#define print(x) cout << x << endl
#define input(x) cin >> x

typedef long long llint;

const llint INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;

struct Point {
  int x, y, p;
};

int main() {
  int n;
  vector<Point> ps;
  vector<pair<int, int>> xs;
  vector<pair<int, int>> ys;

  input(n);

  int x, y, p;
  for (int i = 0; i < n; i++) {
    scanf("%d%d%d", &x, &y, &p);
    ps.push_back({x, y, p});

    xs.push_back({x, i});
    ys.push_back({y, i});
  }

  vector<llint> ans(n + 1, INFLL);
  vector<vector<int>> disx(1 << n);
  vector<vector<int>> disy(1 << n);

  for (int i = 0; i < (1 << n); i++) {
    disx[i] = vector<int>(n, INF);
    for (int j = 0; j < n; j++) {
      disx[i][j] = min(disx[i][j], abs(ps[j].x));
      if ((i & (1 << j)) == 0) {
        continue;
      }
      for (int k = 0; k < n; k++) {
        disx[i][k] = min(disx[i][k], abs(ps[j].x - ps[k].x));
      }
    }
  }

  for (int i = 0; i < (1 << n); i++) {
    disy[i] = vector<int>(n, INF);
    for (int j = 0; j < n; j++) {
      disy[i][j] = min(disy[i][j], abs(ps[j].y));
      if ((i & (1 << j)) == 0) {
        continue;
      }
      for (int k = 0; k < n; k++) {
        disy[i][k] = min(disy[i][k], abs(ps[j].y - ps[k].y));
      }
    }
  }

  int status = 1;
  for (int i = 0; i < n; i++) {
    status *= 3;
  }

  for (int i = 0; i < status; i++) {
    int yy = 0;
    int xx = 0;

    int cur = i;
    int cnt = 0;
    for (int j = 0; j < n; j++) {
      xx <<= 1;
      yy <<= 1;
      int c = cur % 3;
      if (c == 0) {
        // pass
      } else if (c == 1) {
        xx |= 1;
        cnt++;
      } else {
        yy |= 1;
        cnt++;
      }
      cur /= 3;
    }

    vector<int> dis(n, INF);
    for (int j = 0; j < n; j++) {
      dis[j] = min(abs(ps[j].x), abs(ps[j].y));
    }

    for (int j = 0; j < n; j++) {
      dis[j] = min(dis[j], disx[xx][j]);
      dis[j] = min(dis[j], disy[yy][j]);
    }

    llint tot = 0;
    for (int j = 0; j < n; j++) {
      tot += 1LL * dis[j] * ps[j].p;
    }
    ans[cnt] = min(ans[cnt], tot);
  }

  for (int i = 0; i <= n; i++) {
    printf("%lld\\n", ans[i]);
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

#define print(x) cout << x << endl
#define input(x) cin >> x

typedef long long llint;

const llint INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;

#pragma GCC optimize("O3")

struct Point {
  int x, y, p;
};

int main() {
  int n;
  vector<Point> ps;
  vector<pair<int, int>> xs;
  vector<pair<int, int>> ys;

  input(n);

  int x, y, p;
  for (int i = 0; i < n; i++) {
    scanf("%d%d%d", &x, &y, &p);
    ps.push_back({x, y, p});

    xs.push_back({x, i});
    ys.push_back({y, i});
  }

  sort(xs.begin(), xs.end());
  sort(ys.begin(), ys.end());

  int max_status = 1;
  for (int i = 0; i < n; i++) {
    max_status *= 3;
  }

  vector<llint> ans(n + 1, INFLL);

  for (int i = 0; i < max_status; i++) {
    int status = i;

    vector<int> dis(n, INF);
    for (int j = 0; j < n; j++) {
      dis[j] = min(abs(ps[j].x), abs(ps[j].y));
    }

    vector<int> xx;
    xx.reserve(n);

    vector<int> yy;
    yy.reserve(n);

    int cnt = 0;

    for (int j = 0; j < n; j++) {
      int cur = status % 3;
      status /= 3;

      if (cur == 0) {
        // pass
      } else if (cur == 1) {
        xx.push_back(ps[j].x);
        cnt++;
      } else if (cur == 2) {
        yy.push_back(ps[j].y);
        cnt++;
      } else {
        assert(false);
      }
    }

    sort(xx.begin(), xx.end());
    sort(yy.begin(), yy.end());

    {
      int p = 0;
      int q = 0;
      while (p < xs.size() && q <= xx.size()) {
        while (q < xx.size() && xx[q] <= xs[p].first) {
          q++;
        }
        if (p < xs.size() && q < xx.size()) {
          dis[xs[p].second] = min(dis[xs[p].second], abs(xx[q] - xs[p].first));
        }
        if (p < xs.size() && q - 1 >= 0 && q - 1 < xx.size()) {
          dis[xs[p].second] =
              min(dis[xs[p].second], abs(xx[q - 1] - xs[p].first));
        }
        p++;
      }
    }

    {
      int p = 0;
      int q = 0;
      while (p < ys.size() && q <= yy.size()) {
        while (q < yy.size() && yy[q] <= ys[p].first) {
          q++;
        }
        if (p < ys.size() && q < yy.size()) {
          dis[ys[p].second] = min(dis[ys[p].second], abs(yy[q] - ys[p].first));
        }
        if (p < ys.size() && q - 1 >= 0 && q - 1 < yy.size()) {
          dis[ys[p].second] =
              min(dis[ys[p].second], abs(yy[q - 1] - ys[p].first));
        }
        p++;
      }
    }

    llint tot = 0;
    for (int j = 0; j < n; j++) {
      tot += 1LL * dis[j] * ps[j].p;
    }

    ans[cnt] = min(ans[cnt], tot);
  }

  for (auto num : ans) {
    printf("%lld\\n", num);
  }

  return 0;
}