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

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
#define repi(n) for (int i = 0; i < (n); i++)
#define repj(n) for (int j = 0; j < (n); j++)
#define repk(n) for (int k = 0; k < (n); k++)
#define repl(n) for (int l = 0; l < (n); l++)
#define rep(i, n) for (int i = 0; (i) < (n); i++)
#define repr(i, a, b) for (auto i = (a); i < (b); i++)
#define repv(itr) for (auto &&v : (itr))
#define repv2(itr) for (auto &&v2 : (itr))
#define repv3(itr) for (auto &&v3 : (itr))
#define updatemax(t, v) (t = max((t), (v)))
#define updatemin(t, v) (t = min((t), (v)))
const double PI = atan(1.0) * 4;
const double E = exp(1);
ll modpow(ll a, ll b, ll m) {
  ll re = 1, k = 1;
  while (k <= b) {
    if (b & k) {
      re *= a;
      re %= m;
    }
    k = k << 1;
    a *= a;
    a %= m;
    a += m;
    a %= m;
  }
  return re;
}
ll modinv(ll a, ll m) {
  ll b = m, u = 1, v = 0;
  while (b) {
    ll t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0)
    u += m;
  return u;
}
ll modbinomial(ll n, ll k, ll m) {
  k = min(k, n - k);
  if (k < 0)
    return 0;
  ll re = 1;
  for (ll i = 0; i < k; i++) {
    re *= n - i;
    re %= m;
    re *= modinv(i + 1, m);
    re %= m;
  }
  return re;
}
class uftree {
private:
  int n, groups;
  vector<int> parent, size;

public:
  uftree(int _n) {
    groups = n = _n;
    parent.resize(n);
    size.resize(n);
    for (int i = 0; i < n; i++) {
      parent[i] = i;
      size[i] = 1;
    }
  }
  int group(int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = group(parent[x]);
  }
  bool inSameGroup(int x, int y) { return group(x) == group(y); }
  int groupSizeOf(int x) { return size[group(x)]; }
  void merge(int x, int y) {
    int gx = group(x), gy = group(y);
    if (gx != gy) {
      parent[gx] = gy;
      size[gy] += size[gx];
      size[gx] = 0;
      groups--;
    }
  }
  int countGroups() { return groups; }
};
template <typename T> class segtree {
private:
  int n;
  function<T(T, T)> f;
  T e;
  vector<T> data, lazy;
  void _updateP(int i) {
    data[i] = f(data[i * 2 + 1], data[i * 2 + 2]);
    if (i)
      _updateP((i - 1) / 2);
  }
  T _calc(int begin, int end, int node, int nodeBegin, int nodeEnd) {
    if (end <= nodeBegin || nodeEnd <= begin) {
      return e;
    } else if (begin <= nodeBegin && nodeEnd <= end) {
      return data[node];
    } else {
      int m = (nodeBegin + nodeEnd) / 2;
      T left = _calc(begin, end, node * 2 + 1, nodeBegin, m);
      T right = _calc(begin, end, node * 2 + 2, m, nodeEnd);
      return f(left, right);
    }
  }

public:
  segtree(int n_, function<T(T, T)> f_, T e_, T fill) {
    n = pow(2, ceil(log2(n_)));
    f = f_;
    e = e_;
    data.resize(n * 2 - 1);
    for (int i = 0; i < n * 2 - 1; i++)
      data[i] = fill;
  }
  segtree(int n_, function<T(T, T)> f_, T e_) : segtree(n_, f_, e_, e_) {}
  T value(int i) { return data[n - 1 + i]; }
  void update(int i, T value) {
    data[n - 1 + i] = value;
    if (n)
      _updateP((n - 2 + i) / 2);
  }
  T calc(int begin, int end) { return _calc(begin, end, 0, 0, n); }
  static T max(T a, T b) { return std::max(a, b); }
  static T min(T a, T b) { return std::min(a, b); }
  static T sum(T a, T b) { return a + b; }
};

int d, c[26], s[365][26], last[26];
const int depths[] = {10, 8, 6, 4};
const int maxDepth = 4;
pair<int, int> X(int day, int depth = 0) {
  priority_queue<pair<int, int>> vals;
  repi(26) {
    int score = s[day + depth][i];
    repj(26) score -= c[j] * (day + depth - last[j]);
    vals.emplace(score, i);
  }
  if (depth >= min(maxDepth, d - day - 1))
    return vals.top();
  pair<int, int> result(INT_MIN, -1);
  repi(depths[depth]) {
    int v, p;
    tie(v, p) = vals.top();
    vals.pop();
    int last_p_0 = last[p];
    last[p] = day + depth;
    auto ps_ = X(day, depth + 1);
    last[p] = last_p_0;
    if (result.first < ps_.first + v) {
      result.first = ps_.first + v;
      result.second = p;
    }
  }
  return result;
}
int main() {
  cin >> d;
  repi(26) cin >> c[i];
  repi(d) repj(26) cin >> s[i][j];
  repi(26) last[i] = -1;
  repi(d) {
    int maxv, maxj;
    tie(maxv, maxj) = X(i);
    last[maxj] = i;
    cout << maxj + 1 << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
#define repi(n) for (int i = 0; i < (n); i++)
#define repj(n) for (int j = 0; j < (n); j++)
#define repk(n) for (int k = 0; k < (n); k++)
#define repl(n) for (int l = 0; l < (n); l++)
#define rep(i, n) for (int i = 0; (i) < (n); i++)
#define repr(i, a, b) for (auto i = (a); i < (b); i++)
#define repv(itr) for (auto &&v : (itr))
#define repv2(itr) for (auto &&v2 : (itr))
#define repv3(itr) for (auto &&v3 : (itr))
#define updatemax(t, v) (t = max((t), (v)))
#define updatemin(t, v) (t = min((t), (v)))
const double PI = atan(1.0) * 4;
const double E = exp(1);
ll modpow(ll a, ll b, ll m) {
  ll re = 1, k = 1;
  while (k <= b) {
    if (b & k) {
      re *= a;
      re %= m;
    }
    k = k << 1;
    a *= a;
    a %= m;
    a += m;
    a %= m;
  }
  return re;
}
ll modinv(ll a, ll m) {
  ll b = m, u = 1, v = 0;
  while (b) {
    ll t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0)
    u += m;
  return u;
}
ll modbinomial(ll n, ll k, ll m) {
  k = min(k, n - k);
  if (k < 0)
    return 0;
  ll re = 1;
  for (ll i = 0; i < k; i++) {
    re *= n - i;
    re %= m;
    re *= modinv(i + 1, m);
    re %= m;
  }
  return re;
}
class uftree {
private:
  int n, groups;
  vector<int> parent, size;

public:
  uftree(int _n) {
    groups = n = _n;
    parent.resize(n);
    size.resize(n);
    for (int i = 0; i < n; i++) {
      parent[i] = i;
      size[i] = 1;
    }
  }
  int group(int x) {
    if (parent[x] == x)
      return x;
    return parent[x] = group(parent[x]);
  }
  bool inSameGroup(int x, int y) { return group(x) == group(y); }
  int groupSizeOf(int x) { return size[group(x)]; }
  void merge(int x, int y) {
    int gx = group(x), gy = group(y);
    if (gx != gy) {
      parent[gx] = gy;
      size[gy] += size[gx];
      size[gx] = 0;
      groups--;
    }
  }
  int countGroups() { return groups; }
};
template <typename T> class segtree {
private:
  int n;
  function<T(T, T)> f;
  T e;
  vector<T> data, lazy;
  void _updateP(int i) {
    data[i] = f(data[i * 2 + 1], data[i * 2 + 2]);
    if (i)
      _updateP((i - 1) / 2);
  }
  T _calc(int begin, int end, int node, int nodeBegin, int nodeEnd) {
    if (end <= nodeBegin || nodeEnd <= begin) {
      return e;
    } else if (begin <= nodeBegin && nodeEnd <= end) {
      return data[node];
    } else {
      int m = (nodeBegin + nodeEnd) / 2;
      T left = _calc(begin, end, node * 2 + 1, nodeBegin, m);
      T right = _calc(begin, end, node * 2 + 2, m, nodeEnd);
      return f(left, right);
    }
  }

public:
  segtree(int n_, function<T(T, T)> f_, T e_, T fill) {
    n = pow(2, ceil(log2(n_)));
    f = f_;
    e = e_;
    data.resize(n * 2 - 1);
    for (int i = 0; i < n * 2 - 1; i++)
      data[i] = fill;
  }
  segtree(int n_, function<T(T, T)> f_, T e_) : segtree(n_, f_, e_, e_) {}
  T value(int i) { return data[n - 1 + i]; }
  void update(int i, T value) {
    data[n - 1 + i] = value;
    if (n)
      _updateP((n - 2 + i) / 2);
  }
  T calc(int begin, int end) { return _calc(begin, end, 0, 0, n); }
  static T max(T a, T b) { return std::max(a, b); }
  static T min(T a, T b) { return std::min(a, b); }
  static T sum(T a, T b) { return a + b; }
};

int d, c[26], s[365][26], last[26];
const int depths[] = {12, 8, 6, 4, 4, 4};
const int maxDepth = 5;
pair<int, int> X(int day, int depth = 0) {
  priority_queue<pair<int, int>> vals;
  repi(26) {
    int score = s[day + depth][i];
    repj(26) score -= c[j] * (day + depth - last[j]);
    vals.emplace(score, i);
  }
  if (depth >= min(maxDepth, d - day - 1))
    return vals.top();
  pair<int, int> result(INT_MIN, -1);
  repi(depths[depth]) {
    int v, p;
    tie(v, p) = vals.top();
    vals.pop();
    int last_p_0 = last[p];
    last[p] = day + depth;
    auto ps_ = X(day, depth + 1);
    last[p] = last_p_0;
    if (result.first < ps_.first + v) {
      result.first = ps_.first + v;
      result.second = p;
    }
  }
  return result;
}
int main() {
  cin >> d;
  repi(26) cin >> c[i];
  repi(d) repj(26) cin >> s[i][j];
  repi(26) last[i] = -1;
  repi(d) {
    int maxv, maxj;
    tie(maxv, maxj) = X(i);
    last[maxj] = i;
    cout << maxj + 1 << endl;
  }
}