Problem p02618 (C++)

Buggy submission (status: Time Limit Exceeded):
/**
 * @brief atcoder
 * @author yao
 */
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <utility>
#include <vector>
#define ft first
#define sd second
#ifdef DBG
#define dbg_pri(x...) fprintf(stderr, x)
#else
#define dbg_pri(x...) 0
#define NDEBUG
#endif // DBG
#include <cassert>

typedef unsigned int uint;
typedef long long int lli;
typedef unsigned long long int ulli;

#define N 512
#define M 32
#define K (1048576 * 24)
#define T (256 * 6)

int c[M];
int s[N][M];
int t[N], max_t[N];
std::vector<int> poi[M];

constexpr int n = 365, m = 26;

int count() {
  for (int i = 0; i < m; ++i)
    poi[i] = {-1};
  int res = 0;
  for (int i = 0; i < n; ++i) {
    int l = poi[t[i]].back(), d = i - l;
    poi[t[i]].push_back(i);
    res += s[i][t[i]];
    res -= c[t[i]] * d * (d - 1) / 2;
  }
  for (int i = 0; i < m; ++i) {
    int l = poi[i].back(), d = n - l;
    poi[i].push_back(n);
    res -= c[i] * d * (d - 1) / 2;
  }
  return res;
}

int pos, ot, nt;
std::vector<int>::iterator oil, oit, oir, nil, nir;

int update_dryrun(int x, int k) {
  int res;
  pos = x, ot = t[x], nt = k;
  res = s[x][nt] - s[x][ot];
  oit = std::find(poi[ot].begin(), poi[ot].end(), x), oil = std::prev(oit),
  oir = std::next(oit);
  res -= c[ot] * (x - *oil) * (*oir - x);
  nir = std::upper_bound(poi[nt].begin(), poi[nt].end(), x),
  nil = std::prev(nir);
  res += c[nt] * (x - *nil) * (*nir - x);
  return res;
}

void patch() {
  const int &x = pos;
  poi[ot].erase(oit);
  poi[nt].insert(nir, x);
  t[x] = nt;
}

int main() {
  int d;
  scanf("%d", &d);
  assert(d == n);
  for (int i = 0; i < m; ++i)
    scanf("%d", &c[i]);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      scanf("%d", &s[i][j]);
  for (int i = 0; i < n; ++i)
    t[i] = rand() % m;
  memcpy(max_t, t, sizeof(max_t));
  int val = count(), max_val = val;
#ifdef DBG
  int init_val = val;
  int ca = 0, cb = 0;
#endif // DBG
  for (int i = 0; i < K; ++i) {
    int x = rand() % n, k = rand() % (m - 1);
    if (k >= t[x])
      ++k;
    int nxt_v = val + update_dryrun(x, k);
    if (nxt_v >= val ||
        rand() <= (int)(exp((double)(nxt_v - val) / T) * ((lli)RAND_MAX + 1))) {
#ifdef DBG
      (nxt_v < val ? ca : cb)++;
#endif // DBG
      val = nxt_v;
      patch();
      if (max_val < val) {
        max_val = val;
        memcpy(max_t, t, sizeof(max_t));
      }
    }
  }
  for (int i = 0; i < n; ++i)
    printf("%d\n", max_t[i] + 1);
  dbg_pri("poi 3: init=%d max=%d val=%d %d %d\n", init_val, max_val, val, ca,
          cb);
  return 0;
}


Fixed submission:
/**
 * @brief atcoder
 * @author yao
 */
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <utility>
#include <vector>
#define ft first
#define sd second
#ifdef DBG
#define dbg_pri(x...) fprintf(stderr, x)
#else
#define dbg_pri(x...) 0
#define NDEBUG
#endif // DBG
#include <cassert>

typedef unsigned int uint;
typedef long long int lli;
typedef unsigned long long int ulli;

#define N 512
#define M 32
#define K (1048576 * 20)
#define T (256 * 5)

int c[M];
int s[N][M];
int t[N], max_t[N];
std::vector<int> poi[M];

constexpr int n = 365, m = 26;

int count() {
  for (int i = 0; i < m; ++i)
    poi[i] = {-1};
  int res = 0;
  for (int i = 0; i < n; ++i) {
    int l = poi[t[i]].back(), d = i - l;
    poi[t[i]].push_back(i);
    res += s[i][t[i]];
    res -= c[t[i]] * d * (d - 1) / 2;
  }
  for (int i = 0; i < m; ++i) {
    int l = poi[i].back(), d = n - l;
    poi[i].push_back(n);
    res -= c[i] * d * (d - 1) / 2;
  }
  return res;
}

int pos, ot, nt;
std::vector<int>::iterator oil, oit, oir, nil, nir;

int update_dryrun(int x, int k) {
  int res;
  pos = x, ot = t[x], nt = k;
  res = s[x][nt] - s[x][ot];
  oit = std::find(poi[ot].begin(), poi[ot].end(), x), oil = std::prev(oit),
  oir = std::next(oit);
  res -= c[ot] * (x - *oil) * (*oir - x);
  nir = std::upper_bound(poi[nt].begin(), poi[nt].end(), x),
  nil = std::prev(nir);
  res += c[nt] * (x - *nil) * (*nir - x);
  return res;
}

void patch() {
  const int &x = pos;
  poi[ot].erase(oit);
  poi[nt].insert(nir, x);
  t[x] = nt;
}

int main() {
  int d;
  scanf("%d", &d);
  assert(d == n);
  for (int i = 0; i < m; ++i)
    scanf("%d", &c[i]);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      scanf("%d", &s[i][j]);
  for (int i = 0; i < n; ++i)
    t[i] = rand() % m;
  memcpy(max_t, t, sizeof(max_t));
  int val = count(), max_val = val;
#ifdef DBG
  int init_val = val;
  int ca = 0, cb = 0;
#endif // DBG
  for (int i = 0; i < K; ++i) {
    int x = rand() % n, k = rand() % (m - 1);
    if (k >= t[x])
      ++k;
    int nxt_v = val + update_dryrun(x, k);
    if (nxt_v >= val ||
        rand() <= (int)(exp((double)(nxt_v - val) / T) * ((lli)RAND_MAX + 1))) {
#ifdef DBG
      (nxt_v < val ? ca : cb)++;
#endif // DBG
      val = nxt_v;
      patch();
      if (max_val < val) {
        max_val = val;
        memcpy(max_t, t, sizeof(max_t));
      }
    }
  }
  for (int i = 0; i < n; ++i)
    printf("%d\n", max_t[i] + 1);
  dbg_pri("poi 3: init=%d max=%d val=%d %d %d\n", init_val, max_val, val, ca,
          cb);
  return 0;
}