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

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;

const int maxl = 3e5 + 10;
const ll inf = 1ll << 60;

int n, m, cas, k, cnt, totx, toty;
int st[maxl], numx[maxl], numy[maxl];
int xdis[1 << 15][16], ydis[1 << 15][16];
int xlen[1 << 15], ylen[1 << 15];
ll c[maxl], ans[maxl];
struct node {
  int x, y, val, id;
} a[maxl], bx[maxl], by[maxl];
vector<int> tmpx, tmpy;
char s[maxl];
bool inx[maxl], iny[maxl];

inline void prework() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].val);
    a[i].id = i;
    bx[i] = node{a[i].x, a[i].y, a[i].val, i};
    by[i] = node{a[i].x, a[i].y, a[i].val, i};
  }
  for (int i = 0; i <= n; i++)
    ans[i] = inf;
}

inline bool cmpx(const node &a, const node &b) { return a.x < b.x; }

inline bool cmpy(const node &a, const node &b) { return a.y < b.y; }

inline ll dis(int x, int y) { return abs(x - y); }

inline void jug(int sx, int sy) {
  ll tmp = 0;
  int len = xlen[sx] + ylen[sy];
  for (int i = 1; i <= n; i++)
    tmp += 1ll * min(xdis[sx][i], ydis[sy][i]) * a[i].val;
  ans[len] = min(ans[len], tmp);
}

inline void dfs(int k, int sx, int sy) {
  if (k > n)
    jug(sx, sy);
  else {
    dfs(k + 1, sx, sy);
    dfs(k + 1, sx | (1 << (k - 1)), sy);
    dfs(k + 1, sx, sy | (1 << (k - 1)));
  }
}

inline void mainwork() {
  sort(bx + 1, bx + 1 + n, cmpx);
  sort(by + 1, by + 1 + n, cmpy);
  int up = 1 << n;
  for (int s = 0; s < up; s++) {
    tmpx.clear();
    tmpx.push_back(0);
    tmpy.clear();
    tmpy.push_back(0);
    for (int i = 1; i <= n; i++)
      if ((s >> (i - 1)) & 1) {
        tmpx.push_back(a[i].x);
        tmpy.push_back(a[i].y);
      }
    sort(tmpx.begin(), tmpx.end());
    sort(tmpy.begin(), tmpy.end());
    tmpx.erase(unique(tmpx.begin(), tmpx.end()), tmpx.end());
    tmpy.erase(unique(tmpy.begin(), tmpy.end()), tmpy.end());
    int id = 0;
    xlen[s] = tmpx.size();
    for (int i = 1; i <= n; i++) {
      while (id + 1 < xlen[s] &&
             dis(bx[i].x, tmpx[id + 1]) < dis(bx[i].x, tmpx[id]))
        ++id;
      xdis[s][bx[i].id] = dis(bx[i].x, tmpx[id]);
    }
    id = 0;
    ylen[s] = tmpy.size();
    for (int i = 1; i <= n; i++) {
      while (id + 1 < ylen[s] &&
             dis(by[i].y, tmpy[id + 1]) < dis(by[i].y, tmpy[id]))
        ++id;
      ydis[s][by[i].id] = dis(by[i].y, tmpy[id]);
    }
    --xlen[s];
    --ylen[s];
  }
  dfs(1, 0, 0);
  for (int i = n; i >= 0; i--) {
    if (ans[i] != inf)
      break;
    ans[i] = 0;
  }
}

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

int main() {
  int t = 1;
  // scanf("%d",&t);
  for (cas = 1; cas <= t; cas++) {
    prework();
    mainwork();
    print();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;

const int maxl = 3e5 + 10;

int n, m, cas, k, cnt, totx, toty;
int st[maxl], numx[maxl], numy[maxl];
ll c[maxl], ans[maxl];
struct node {
  int x, y, val, id;
} a[maxl], bx[maxl], by[maxl];
vector<int> tmpx, tmpy;
char s[maxl];
bool inx[maxl], iny[maxl];

inline void prework() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].val);
    a[i].id = i;
    bx[i] = node{a[i].x, a[i].y, a[i].val, i};
    by[i] = node{a[i].x, a[i].y, a[i].val, i};
  }
  for (int i = 0; i <= n; i++)
    ans[i] = 1ll << 60;
}

inline bool cmpx(const node &a, const node &b) { return a.x < b.x; }

inline bool cmpy(const node &a, const node &b) { return a.y < b.y; }

inline ll dis(int x, int y) { return abs(x - y); }

inline void jug() {
  tmpx.clear();
  tmpy.clear();
  for (int i = 1; i <= n; i++) {
    if (st[i] == 1) {
      inx[i] = true;
      iny[i] = false;
    } else if (st[i] == 2) {
      inx[i] = false;
      iny[i] = true;
    } else
      inx[i] = iny[i] = false;
    c[i] = min(abs(a[i].x), abs(a[i].y));
  }
  for (int i = 1; i <= n; i++)
    if (inx[bx[i].id])
      tmpx.push_back(bx[i].x);
  for (int i = 1; i <= n; i++)
    if (iny[by[i].id])
      tmpy.push_back(by[i].y);
  int id = 0, xlen = tmpx.size(), ylen = tmpy.size();
  if (xlen > 0) {
    for (int i = 1; i <= n; i++) {
      while (id + 1 < xlen &&
             dis(bx[i].x, tmpx[id + 1]) < dis(bx[i].x, tmpx[id]))
        ++id;
      c[bx[i].id] = min(c[bx[i].id], dis(bx[i].x, tmpx[id]));
    }
  }
  id = 0;
  if (ylen > 0) {
    for (int i = 1; i <= n; i++) {
      while (id + 1 < ylen &&
             dis(by[i].y, tmpy[id + 1]) < dis(by[i].y, tmpy[id]))
        ++id;
      c[by[i].id] = min(c[by[i].id], dis(by[i].y, tmpy[id]));
    }
  }
  ll tmp = 0, len = xlen + ylen;
  for (int i = 1; i <= n; i++)
    tmp += 1ll * c[i] * a[i].val;
  ans[len] = min(ans[len], tmp);
}

inline void dfs(int k) {
  if (k > n)
    jug();
  else {
    st[k] = 0;
    dfs(k + 1);
    st[k] = 1;
    dfs(k + 1);
    st[k] = 2;
    dfs(k + 1);
  }
}

inline void mainwork() {
  sort(bx + 1, bx + 1 + n, cmpx);
  sort(by + 1, by + 1 + n, cmpy);
  dfs(1);
}

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

int main() {
  int t = 1;
  // scanf("%d",&t);
  for (cas = 1; cas <= t; cas++) {
    prework();
    mainwork();
    print();
  }
  return 0;
}