Problem p02618 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
using ll = long long;
constexpr int inf = 1e9 + 7;
constexpr ll longinf = 1LL << 60;
constexpr ll mod = 1e9 + 7;

const int N = 365, M = 26;
int c[26], s[365][26];
int res[365];

set<int> st[26];

int calc() {
  int ret = 0;
  vector<int> last(26, -1);
  rep(i, N) {
    ret += s[i][res[i]];
    last[res[i]] = i;
    rep(j, 26) ret -= c[j] * (i - last[j]);
  }
  return ret;
}
inline int f(int n) { return n * (n - 1) / 2; }

int erase(int i, int j) {
  auto itr = st[i].lower_bound(j);
  int nxt = *(next(itr)), prv = *(prev(itr));
  return -s[j][i] + c[i] * (f(j - prv) + f(nxt - j) - f(nxt - prv));
}
int insert(int i, int j) {
  auto itr = st[i].lower_bound(j);
  int nxt = *itr, prv = *(prev(itr));
  return s[j][i] + c[i] * (-f(j - prv) - f(nxt - j) + f(nxt - prv));
}
struct Xor128 {
  unsigned x, y, z, w;

  Xor128(unsigned w_ = 88675123)
      : x(123456789), y(362436069), z(521288629), w(w_){};

  inline unsigned xor128() {
    unsigned t;
    t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }

  int nextInt(int x, int y) {
    if (x > y)
      swap(x, y);
    return xor128() % (y - x) + x;
  }

  double nextDouble(double a, double b) {
    return (double)(xor128() & 0xffff) / 0xffff * (b - a) + a;
  }
};

const int T = 2e7;
const double startT = 0, endT = 1000;
int main() {
  int _;
  cin >> _;
  rep(i, M) cin >> c[i];
  rep(i, N) rep(j, M) cin >> s[i][j];
  rep(i, M) st[i].insert(-1);
  rep(i, M) st[i].insert(N);
  auto rnd = Xor128();
  rep(i, N) {
    res[i] = rnd.nextInt(0, M);
    st[res[i]].insert(i);
  }
  int cur = calc();
  rep(loop, T) {
    int day = rnd.nextInt(0, N), con = rnd.nextInt(0, M);
    if (res[day] == con)
      continue;
    int diff = insert(con, day) + erase(res[day], day);
    double temp = startT + (endT - startT) * loop / T;
    double prob = exp((double)diff / temp);
    if (prob > rnd.nextDouble(0, 1) || diff > 0) {
      cur += diff;
      st[res[day]].erase(day);
      st[con].insert(day);
      res[day] = con;
    }
  }
  rep(i, N) cout << res[i] + 1 << endl;
  cerr << cur << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
using ll = long long;
constexpr int inf = 1e9 + 7;
constexpr ll longinf = 1LL << 60;
constexpr ll mod = 1e9 + 7;

const int N = 365, M = 26;
int c[26], s[365][26];
int res[365];

set<int> st[26];

int calc() {
  int ret = 0;
  vector<int> last(26, -1);
  rep(i, N) {
    ret += s[i][res[i]];
    last[res[i]] = i;
    rep(j, 26) ret -= c[j] * (i - last[j]);
  }
  return ret;
}
inline int f(int n) { return n * (n - 1) / 2; }

int erase(int i, int j) {
  auto itr = st[i].lower_bound(j);
  int nxt = *(next(itr)), prv = *(prev(itr));
  return -s[j][i] + c[i] * (f(j - prv) + f(nxt - j) - f(nxt - prv));
}
int insert(int i, int j) {
  auto itr = st[i].lower_bound(j);
  int nxt = *itr, prv = *(prev(itr));
  return s[j][i] + c[i] * (-f(j - prv) - f(nxt - j) + f(nxt - prv));
}
struct Xor128 {
  unsigned x, y, z, w;

  Xor128(unsigned w_ = 88675123)
      : x(123456789), y(362436069), z(521288629), w(w_){};

  inline unsigned xor128() {
    unsigned t;
    t = x ^ (x << 11);
    x = y;
    y = z;
    z = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  }

  int nextInt(int x, int y) {
    if (x > y)
      swap(x, y);
    return xor128() % (y - x) + x;
  }

  double nextDouble(double a, double b) {
    return (double)(xor128() & 0xffff) / 0xffff * (b - a) + a;
  }
};

const int T = 15000000;
const double startT = 0, endT = 1000;
int main() {
  int _;
  cin >> _;
  rep(i, M) cin >> c[i];
  rep(i, N) rep(j, M) cin >> s[i][j];
  rep(i, M) st[i].insert(-1);
  rep(i, M) st[i].insert(N);
  auto rnd = Xor128();
  rep(i, N) {
    res[i] = rnd.nextInt(0, M);
    st[res[i]].insert(i);
  }
  int cur = calc();
  rep(loop, T) {
    int day = rnd.nextInt(0, N), con = rnd.nextInt(0, M);
    if (res[day] == con)
      continue;
    int diff = insert(con, day) + erase(res[day], day);
    double temp = startT + (endT - startT) * loop / T;
    double prob = exp((double)diff / temp);
    if (prob > rnd.nextDouble(0, 1) || diff > 0) {
      cur += diff;
      st[res[day]].erase(day);
      st[con].insert(day);
      res[day] = con;
    }
  }
  rep(i, N) cout << res[i] + 1 << endl;
  cerr << cur << endl;
  return 0;
}