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

#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define pb push_back
#define mp make_pair
#define FI first
#define SE second
#define maxn 30
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef double db;

int x[maxn + 5], y[maxn + 5], w[maxn + 5];
int idx[20010], idy[20010];

vi lst[20][20];

int main() {
  int N;
  scanf("%d", &N);
  int n = 0, m = 0;
  rep(i, 1, N) scanf("%d%d%d", &x[i], &y[i], &w[i]);

  rep(i, 1, N) rep(j, i + 1, N) if (y[i] > y[j]) {
    swap(x[i], x[j]);
    swap(y[i], y[j]);
    swap(w[i], w[j]);
  }

  vi A, B;
  rep(i, 1, N) A.pb(x[i]);
  rep(i, 1, N) B.pb(y[i]);
  sort(A.begin(), A.end());
  A.erase(unique(A.begin(), A.end()), A.end());
  sort(B.begin(), B.end());
  B.erase(unique(B.begin(), B.end()), B.end());
  for (auto xx : A)
    idx[xx + 10000] = n++;
  for (auto yy : B)
    idy[yy + 10000] = m++;

  rep(i, 0, N) rep(j, 0, (1 << i) - 1) lst[i][__builtin_popcount(j)].pb(j);
  rep(k, 0, N) {
    ll ans = 1ll << 60;
    rep(i, 0, k) {
      for (auto s : lst[n][i]) {
        // printf("!! %d\\n",s);
        bool mark[20] = {};
        vi X;
        rep(z, 1, N) if (((s >> idx[x[z] + 10000]) & 1) == 0)
            mark[idy[y[z] + 10000]] = 1;
        else X.pb(x[z]);
        vector<pii> ch;
        rep(z, 1, N) if (((s >> idx[x[z] + 10000]) & 1) == 0) {
          int d = inf;
          for (auto xx : X)
            d = min(d, abs(xx - x[z]));
          ch.pb(mp(z, d));
        }
        vi Y;
        rep(j, 0, m - 1) if (mark[j]) Y.pb(B[j]);
        int M = (int)Y.size();
        if (M <= k - i) {
          ans = 0;
          break;
        }
        // printf("# %d, %d\\n",M,k-i);
        for (auto t : lst[M][k - i]) {
          // printf("??? %d\\n",t);
          vi tmp;
          rep(j, 0, M - 1) if ((t >> j) & 1) tmp.pb(Y[j]);
          ll sum = 0;
          int ptr = 0;
          for (auto it : ch) {
            int id = it.FI;
            int d = min(abs(x[id]), abs(y[id]));
            d = min(d, it.SE);
            while (ptr < k - i && tmp[ptr] < y[id])
              ptr++;
            if (ptr != 0)
              d = min(d, abs(y[id] - tmp[ptr - 1]));
            if (ptr != k - i)
              d = min(d, abs(y[id] - tmp[ptr]));
            // for(auto xx: X) d=min(d,abs(x[id]-xx));
            // rep(j,0,M-1) if((t>>j)&1) d=min(d,abs(Y[j]-y[id]));
            // printf("?? %d %d\\n",d,w[id]);
            sum += 1ll * d * w[id];
          }
          ans = min(ans, sum);
        }
      }
    }
    printf("%lld\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define pb push_back
#define mp make_pair
#define FI first
#define SE second
#define maxn 30
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef double db;

int x[maxn + 5], y[maxn + 5], w[maxn + 5];
int idx[20010], idy[20010];

vi lst[20][20];

int main() {
  int N;
  scanf("%d", &N);
  int n = 0, m = 0;
  rep(i, 1, N) scanf("%d%d%d", &x[i], &y[i], &w[i]);
  vi A, B;
  rep(i, 1, N) A.pb(x[i]);
  rep(i, 1, N) B.pb(y[i]);
  sort(A.begin(), A.end());
  A.erase(unique(A.begin(), A.end()), A.end());
  sort(B.begin(), B.end());
  B.erase(unique(B.begin(), B.end()), B.end());
  for (auto xx : A)
    idx[xx + 10000] = n++;
  for (auto yy : B)
    idy[yy + 10000] = m++;

  rep(i, 0, N) rep(j, 0, (1 << i) - 1) lst[i][__builtin_popcount(j)].pb(j);

  rep(k, 0, N) {
    ll ans = 1ll << 60;
    rep(i, 0, k) {
      for (auto s : lst[n][i]) {
        // printf("!! %d\\n",s);
        bool mark[20] = {};
        vi X;
        vi ch;
        rep(z, 1, N) if (((s >> idx[x[z] + 10000]) & 1) == 0)
            mark[idy[y[z] + 10000]] = 1,
                            ch.pb(z);
        else X.pb(x[z]);
        vi Y;
        rep(j, 0, m - 1) if (mark[j]) Y.pb(B[j]);
        int M = (int)Y.size();
        if (M <= k - i) {
          ans = 0;
          break;
        }
        // printf("# %d, %d\\n",M,k-i);
        for (auto t : lst[M][k - i]) {
          // printf("??? %d\\n",t);
          ll sum = 0;
          for (auto id : ch) {
            int d = min(abs(x[id]), abs(y[id]));
            for (auto xx : X)
              d = min(d, abs(x[id] - xx));
            rep(j, 0, M - 1) if ((t >> j) & 1) d = min(d, abs(y[id] - Y[j]));
            // printf("?? %d %d\\n",d,w[id]);
            sum += 1ll * d * w[id];
          }
          ans = min(ans, sum);
        }
      }
    }
    printf("%lld\\n", ans);
  }
  return 0;
}