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

#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx")
#include <algorithm>
#include <array>
#include <chrono>
#include <iostream>
#include <random>
#include <vector>
using namespace std;
struct fast_ios {
  fast_ios() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
  };
} fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end)                                                     \\
  for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \\
  for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
template <typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template <typename T, typename... Args>
void ndarray(vector<T> &vec, int len, Args... args) {
  vec.resize(len);
  for (auto &v : vec)
    ndarray(v, args...);
}
template <typename V, typename T> void ndfill(V &x, const T &val) { x = val; }
template <typename V, typename T> void ndfill(vector<V> &vec, const T &val) {
  for (auto &v : vec)
    ndfill(v, val);
}
template <typename T> bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &m, const T q) {
  if (m > q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
#define dbg(x)                                                                 \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

constexpr int Z = 26;
constexpr int D = 365;
array<int, Z> C;
vector<vector<int>> S;

vector<int> schedule;
vector<vector<int>> prv, nxt;
int current_score;

vector<int> calc_score() {
  vector<int> last(26, 0);
  vector<int> ret;
  FOR(d, 1, schedule.size()) {
    current_score += S[d][schedule[d]];
    last[schedule[d]] = d;
    prv[d + 1][schedule[d]] = d;
    nxt[d - 1][schedule[d]] = d;
    REP(i, Z) current_score -= C[i] * (d - last[i]);
    ret.emplace_back(current_score);
  }
  REP(d, schedule.size()) REP(i, Z) chmax(prv[d + 1][i], prv[d][i]);
  IREP(d, schedule.size()) REP(i, Z) chmin(nxt[d][i], nxt[d + 1][i]);
  return ret;
}

void modify(int day, int contest) {
  int cold = schedule[day];
  if (cold == contest)
    return;

  int dprv = prv[day][cold], dnxt = nxt[day][cold];
  nxt[dprv][cold] = dnxt;
  prv[dnxt][cold] = dprv;
  FOR(d, dprv + 1, dnxt) nxt[d][cold] = dnxt, prv[d][cold] = dprv;

  current_score -= C[cold] * (day - dprv) * (dnxt - day) + S[day][cold];

  schedule[day] = contest;

  dprv = prv[day][contest], dnxt = nxt[day][contest];
  nxt[day][contest] = dnxt, prv[day][contest] = dprv;

  FOR(d, dprv, day) nxt[d][contest] = day;
  FOR(d, day + 1, dnxt + 1) prv[d][contest] = day;

  current_score += C[contest] * (day - dprv) * (dnxt - day) + S[day][contest];
}

uint32_t rand_int() // XorShift random integer generator
{
  static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;
  uint32_t t = x ^ (x << 11);
  x = y;
  y = z;
  z = w;
  return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}

// struct rand_int_
// {
//     using lint = long long;
//     mt19937 mt;
//     rand_int_() : mt(chrono::steady_clock::now().time_since_epoch().count())
//     {} lint operator()(lint x) { return this->operator()(0, x); } // [0, x)
//     lint operator()(lint l, lint r)
//     {
//         uniform_int_distribution<lint> d(l, r - 1);
//         return d(mt);
//     }
// } rnd;

void output() {
  FOR(i, 1, schedule.size()) { cout << schedule[i] + 1 << '\\n'; }
  exit(0);
}
int main() {
  auto START = std::chrono::system_clock::now();

  int d_;
  cin >> d_;
  REP(i, Z) cin >> C[i];
  S.resize(D + 1);
  ndarray(S, D + 1, Z);
  REP(d, D) REP(i, Z) cin >> S[d + 1][i];

  ndarray(prv, D + 2, Z);
  ndfill(prv, 0);
  ndarray(nxt, D + 2, Z);
  ndfill(nxt, D + 1);

  schedule.resize(D + 1);
  FOR(d, 1, D + 1) {
    schedule[d] = max_element(S[d].begin(), S[d].end()) - S[d].begin();
  }
  calc_score();

  // output();
  // modify(day, q) day: 1-indexed, 0<=q<26
  vector<int> jun(D);
  std::random_device seed_gen;
  std::mt19937 engine(seed_gen());
  iota(ALL(jun), 1);

  int cnt = 0;
  while (true) {
    cnt++;
    if (rand_int() % 800 == 0) {
      shuffle(ALL(jun), engine);
      for (auto d : jun) {
        int h = current_score, argh = schedule[d];
        REP(i, Z) {
          modify(d, i);
          if (chmax(h, current_score))
            argh = i;
        }
        modify(d, argh);
      }
    } else {
      int d = rand_int() % (D - 1) + 1;
      int e = d + rand_int() % min(D - d, 20) + 1;
      int sd = schedule[d], se = schedule[e];

      int h = current_score;
      modify(d, se);
      modify(e, sd);
      constexpr int width = 8;
      if (chmax(h, current_score)) {
        FOR(f, d - width, d + width + 1) if (f >= 1 and f <= D) {
          int h = current_score, argh = schedule[f];
          REP(i, Z) if (i != schedule[f]) {
            modify(f, i);
            if (chmax(h, current_score))
              argh = i;
          }
          modify(f, argh);
        }
        FOR(f, e - width, e + width + 1) if (f >= 1 and f <= D) {
          int h = current_score, argh = schedule[f];
          REP(i, Z) if (i != schedule[f]) {
            modify(f, i);
            if (chmax(h, current_score))
              argh = i;
          }
          modify(f, argh);
        }
      } else {
        modify(d, sd);
        modify(e, se);
      }
    }

    if (chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now() - START)
            .count() > 1950) {
      dbg(cnt);
      // dbg(current_score);
      output();
      cout << current_score << '\\n';
      exit(0);
    }
  }
}


Error: TLE

Fixed submission:

#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx")
#include <algorithm>
#include <array>
#include <chrono>
#include <iostream>
#include <random>
#include <vector>
using namespace std;
struct fast_ios {
  fast_ios() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
  };
} fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end)                                                     \\
  for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \\
  for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
template <typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template <typename T, typename... Args>
void ndarray(vector<T> &vec, int len, Args... args) {
  vec.resize(len);
  for (auto &v : vec)
    ndarray(v, args...);
}
template <typename V, typename T> void ndfill(V &x, const T &val) { x = val; }
template <typename V, typename T> void ndfill(vector<V> &vec, const T &val) {
  for (auto &v : vec)
    ndfill(v, val);
}
template <typename T> bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &m, const T q) {
  if (m > q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
#define dbg(x)                                                                 \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

constexpr int Z = 26;
constexpr int D = 365;
array<int, Z> C;
vector<vector<int>> S;

vector<int> schedule;
vector<vector<int>> prv, nxt;
int current_score;

vector<int> calc_score() {
  vector<int> last(26, 0);
  vector<int> ret;
  FOR(d, 1, schedule.size()) {
    current_score += S[d][schedule[d]];
    last[schedule[d]] = d;
    prv[d + 1][schedule[d]] = d;
    nxt[d - 1][schedule[d]] = d;
    REP(i, Z) current_score -= C[i] * (d - last[i]);
    ret.emplace_back(current_score);
  }
  REP(d, schedule.size()) REP(i, Z) chmax(prv[d + 1][i], prv[d][i]);
  IREP(d, schedule.size()) REP(i, Z) chmin(nxt[d][i], nxt[d + 1][i]);
  return ret;
}

void modify(int day, int contest) {
  int cold = schedule[day];
  if (cold == contest)
    return;

  int dprv = prv[day][cold], dnxt = nxt[day][cold];
  nxt[dprv][cold] = dnxt;
  prv[dnxt][cold] = dprv;
  FOR(d, dprv + 1, dnxt) nxt[d][cold] = dnxt, prv[d][cold] = dprv;

  current_score -= C[cold] * (day - dprv) * (dnxt - day) + S[day][cold];

  schedule[day] = contest;

  dprv = prv[day][contest], dnxt = nxt[day][contest];
  nxt[day][contest] = dnxt, prv[day][contest] = dprv;

  FOR(d, dprv, day) nxt[d][contest] = day;
  FOR(d, day + 1, dnxt + 1) prv[d][contest] = day;

  current_score += C[contest] * (day - dprv) * (dnxt - day) + S[day][contest];
}

uint32_t rand_int() // XorShift random integer generator
{
  static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;
  uint32_t t = x ^ (x << 11);
  x = y;
  y = z;
  z = w;
  return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}

// struct rand_int_
// {
//     using lint = long long;
//     mt19937 mt;
//     rand_int_() : mt(chrono::steady_clock::now().time_since_epoch().count())
//     {} lint operator()(lint x) { return this->operator()(0, x); } // [0, x)
//     lint operator()(lint l, lint r)
//     {
//         uniform_int_distribution<lint> d(l, r - 1);
//         return d(mt);
//     }
// } rnd;

void output() {
  FOR(i, 1, schedule.size()) { cout << schedule[i] + 1 << '\\n'; }
  exit(0);
}
int main() {
  auto START = std::chrono::system_clock::now();

  int d_;
  cin >> d_;
  REP(i, Z) cin >> C[i];
  S.resize(D + 1);
  ndarray(S, D + 1, Z);
  REP(d, D) REP(i, Z) cin >> S[d + 1][i];

  ndarray(prv, D + 2, Z);
  ndfill(prv, 0);
  ndarray(nxt, D + 2, Z);
  ndfill(nxt, D + 1);

  schedule.resize(D + 1);
  FOR(d, 1, D + 1) {
    schedule[d] = max_element(S[d].begin(), S[d].end()) - S[d].begin();
  }
  calc_score();

  // output();
  // modify(day, q) day: 1-indexed, 0<=q<26
  vector<int> jun(D);
  std::random_device seed_gen;
  std::mt19937 engine(seed_gen());
  iota(ALL(jun), 1);

  int cnt = 0;
  while (true) {
    cnt++;
    if (rand_int() % 100 == 0) {
      shuffle(ALL(jun), engine);
      for (auto d : jun) {
        int h = current_score, argh = schedule[d];
        REP(i, Z) {
          modify(d, i);
          if (chmax(h, current_score))
            argh = i;
        }
        modify(d, argh);
      }
    } else {
      int d = rand_int() % (D - 1) + 1;
      int e = d + rand_int() % min(D - d, 20) + 1;
      int sd = schedule[d], se = schedule[e];

      int h = current_score;
      modify(d, se);
      modify(e, sd);
      if (chmax(h, current_score)) {
        FOR(i, d - 10, d + 10) if (i >= 1 and i <= D) {
          int h = current_score, argh = schedule[i];
          REP(i, Z) {
            modify(d, i);
            if (chmax(h, current_score))
              argh = i;
          }
          modify(d, argh);
        }
      } else {
        modify(d, sd);
        modify(e, se);
      }
    }

    if (chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now() - START)
            .count() > 1990) {
      dbg(cnt);
      // dbg(current_score);
      output();
      cout << current_score << '\\n';
      exit(0);
    }
  }
}