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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using namespace std;
using ll = long long;
using P = pair<int, int>;
using pll = pair<long long, long long>;
constexpr int INF = 1e9;
constexpr long long LINF = 1e17;
constexpr int MOD = 1000000007;
constexpr double PI = 3.14159265358979323846;
const int d = 365;
const double MX_SEC = 1.87;
// const int d = 5;
int c[26];
int s[d][26];
int last[26] = {0};
bool llast[d][26] = {false};
vector<int> solution(d, -1);
int myscore = 0;

random_device seed_gen;
mt19937 mt(seed_gen());
uniform_int_distribution<int> con(0, 26 - 1);
uniform_int_distribution<int> day(0, 365 - 1);
uniform_int_distribution<int> num(0, 20);
uniform_real_distribution<double> pro(0.0, 1.0);

int score(vector<int> t) {
  vector<int> last(26, 0);
  int ans = 0;
  rep(i, d) {
    ans += s[i][t[i]];
    last[t[i]] = i + 1;
    rep(j, 26) ans -= c[j] * (i + 1 - last[j]);
    // cout << ans << endl;
  }
  return ans;
}

// p day contest changes q
void better(int p, int q, clock_t start, clock_t end) {
  // cout << myscore << endl;
  int origin = solution[p];
  int newscore = myscore - s[p][origin] + s[p][q];
  int before_origin = 0, before_q = 0;
  int res = 0;
  for (int i = 0; i < d; i++) {
    if (llast[i][origin])
      before_origin = i + 1;
    if (llast[i][q])
      before_q = i + 1;
    res += (c[origin] * (i + 1 - before_origin) + c[q] * (i + 1 - before_q));
  }

  llast[p][q] = true;
  llast[p][origin] = false;
  before_origin = 0;
  before_q = 0;

  for (int i = 0; i < d; i++) {
    if (llast[i][origin])
      before_origin = i + 1;
    if (llast[i][q])
      before_q = i + 1;
    res -= (c[origin] * (i + 1 - before_origin) + c[q] * (i + 1 - before_q));
  }

  // cout << res << endl;

  double t = 1 - ((double)(end - start) / CLOCKS_PER_SEC) / MX_SEC;
  // cout << t << endl;

  newscore += res;
  if (newscore - myscore > 0 ||
      (exp((double)(newscore - myscore) / t) > pro(mt))) {
    myscore = newscore;
    solution[p] = q;
  } else {
    llast[p][q] = false;
    llast[p][origin] = true;
  }
}

// p day contest swap q day contest
void betterswap(int p, int q, clock_t start, clock_t end) {
  int p_origin = solution[p];
  int q_origin = solution[q];
  int newscore = myscore;
  newscore -= s[p][p_origin] + s[q][q_origin];
  newscore += s[p][q_origin] + s[q][p_origin];

  int before_p_origin = 0, before_q_origin = 0;
  int res = 0;
  for (int i = 0; i < d; i++) {
    if (llast[i][p_origin])
      before_p_origin = i + 1;
    if (llast[i][q_origin])
      before_q_origin = i + 1;
    res += (c[p_origin] * (i + 1 - before_p_origin) +
            c[q_origin] * (i + 1 - before_q_origin));
  }

  llast[p][q_origin] = true, llast[p][p_origin] = false;
  llast[q][p_origin] = true, llast[q][q_origin] = false;
  before_p_origin = 0;
  before_q_origin = 0;

  for (int i = 0; i < d; i++) {
    if (llast[i][p_origin])
      before_p_origin = i + 1;
    if (llast[i][q_origin])
      before_q_origin = i + 1;
    res -= (c[p_origin] * (i + 1 - before_p_origin) +
            c[q_origin] * (i + 1 - before_q_origin));
  }

  double t = 1 - ((double)(end - start) / CLOCKS_PER_SEC) / MX_SEC;

  newscore += res;
  if (newscore - myscore > 0 ||
      (exp((double)(newscore - myscore) / t) > pro(mt))) {
    myscore = newscore;
    solution[p] = q_origin;
    solution[q] = p_origin;
  } else {
    llast[p][q_origin] = false, llast[p][p_origin] = true;
    llast[q][p_origin] = false, llast[q][q_origin] = true;
  }
}

// day 1-index i_day 's contest is k
int nowscore(int i, int k) {
  int res = s[i][k];
  int before = last[k];
  last[k] = i + 1;
  rep(j, 26) res -= c[j] * (i + 1 - last[j]);
  last[k] = before;
  return res;
}

int main() {
  clock_t start = clock();

  int tmp;
  cin >> tmp;
  rep(i, 26) cin >> c[i];
  rep(i, d) rep(j, 26) cin >> s[i][j];

  for (int i = 0; i < d; i++) {
    int id = -1;
    int mx = -INF;
    for (int j = 0; j < 26; j++) {
      int res = nowscore(i, j);
      if (mx < res) {
        id = j;
        mx = res;
      }
    }
    solution[i] = id;
    last[id] = i + 1;
    llast[i][id] = true;
    myscore += mx;
  }

  clock_t end = clock();

  while (((double)(end - start) / CLOCKS_PER_SEC) < MX_SEC) {
    int k = day(mt);
    betterswap(k, min(k + num(mt), 365 - 1), start, end);
    better(day(mt), con(mt), start, end);
    end = clock();
  }

  rep(i, d) cout << solution[i] + 1 << endl;
  /*
  cout << myscore << endl;
  cout << (score(solution) + 1e6) << endl;
  cout << (myscore + 1e6) << endl;
  */

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using namespace std;
using ll = long long;
using P = pair<int, int>;
using pll = pair<long long, long long>;
constexpr int INF = 1e9;
constexpr long long LINF = 1e17;
constexpr int MOD = 1000000007;
constexpr double PI = 3.14159265358979323846;
const int d = 365;
const double MX_SEC = 3.0;
// const int d = 5;
int c[26];
int s[d][26];
int last[26] = {0};
bool llast[d][26] = {false};
vector<int> solution(d, -1);
int myscore = 0;

random_device seed_gen;
mt19937 mt(seed_gen());
uniform_int_distribution<int> con(0, 26 - 1);
uniform_int_distribution<int> day(0, 365 - 1);
uniform_int_distribution<int> num(0, 20);
uniform_real_distribution<double> pro(0.0, 1.0);

int score(vector<int> t) {
  vector<int> last(26, 0);
  int ans = 0;
  rep(i, d) {
    ans += s[i][t[i]];
    last[t[i]] = i + 1;
    rep(j, 26) ans -= c[j] * (i + 1 - last[j]);
    // cout << ans << endl;
  }
  return ans;
}

// p day contest changes q
void better(int p, int q, clock_t start, clock_t end) {
  // cout << myscore << endl;
  int origin = solution[p];
  int newscore = myscore - s[p][origin] + s[p][q];
  int before_origin = 0, before_q = 0;
  int res = 0;
  for (int i = 0; i < d; i++) {
    if (llast[i][origin])
      before_origin = i + 1;
    if (llast[i][q])
      before_q = i + 1;
    res += (c[origin] * (i + 1 - before_origin) + c[q] * (i + 1 - before_q));
  }

  llast[p][q] = true;
  llast[p][origin] = false;
  before_origin = 0;
  before_q = 0;

  for (int i = 0; i < d; i++) {
    if (llast[i][origin])
      before_origin = i + 1;
    if (llast[i][q])
      before_q = i + 1;
    res -= (c[origin] * (i + 1 - before_origin) + c[q] * (i + 1 - before_q));
  }

  // cout << res << endl;

  double t = 1 - ((double)(end - start) / CLOCKS_PER_SEC) / MX_SEC;
  // cout << t << endl;

  newscore += res;
  if (newscore - myscore > 0 ||
      (exp((double)(newscore - myscore) / t) > pro(mt))) {
    myscore = newscore;
    solution[p] = q;
  } else {
    llast[p][q] = false;
    llast[p][origin] = true;
  }
}

// p day contest swap q day contest
void betterswap(int p, int q, clock_t start, clock_t end) {
  int p_origin = solution[p];
  int q_origin = solution[q];
  int newscore = myscore;
  newscore -= s[p][p_origin] + s[q][q_origin];
  newscore += s[p][q_origin] + s[q][p_origin];

  int before_p_origin = 0, before_q_origin = 0;
  int res = 0;
  for (int i = 0; i < d; i++) {
    if (llast[i][p_origin])
      before_p_origin = i + 1;
    if (llast[i][q_origin])
      before_q_origin = i + 1;
    res += (c[p_origin] * (i + 1 - before_p_origin) +
            c[q_origin] * (i + 1 - before_q_origin));
  }

  llast[p][q_origin] = true, llast[p][p_origin] = false;
  llast[q][p_origin] = true, llast[q][q_origin] = false;
  before_p_origin = 0;
  before_q_origin = 0;

  for (int i = 0; i < d; i++) {
    if (llast[i][p_origin])
      before_p_origin = i + 1;
    if (llast[i][q_origin])
      before_q_origin = i + 1;
    res -= (c[p_origin] * (i + 1 - before_p_origin) +
            c[q_origin] * (i + 1 - before_q_origin));
  }

  double t = 1 - ((double)(end - start) / CLOCKS_PER_SEC) / MX_SEC;

  newscore += res;
  if (newscore - myscore > 0 ||
      (exp((double)(newscore - myscore) / t) > pro(mt))) {
    myscore = newscore;
    solution[p] = q_origin;
    solution[q] = p_origin;
  } else {
    llast[p][q_origin] = false, llast[p][p_origin] = true;
    llast[q][p_origin] = false, llast[q][q_origin] = true;
  }
}

// day 1-index i_day 's contest is k
int nowscore(int i, int k) {
  int res = s[i][k];
  int before = last[k];
  last[k] = i + 1;
  rep(j, 26) res -= c[j] * (i + 1 - last[j]);
  last[k] = before;
  return res;
}

int main() {
  clock_t start = clock();

  int tmp;
  cin >> tmp;
  rep(i, 26) cin >> c[i];
  rep(i, d) rep(j, 26) cin >> s[i][j];

  for (int i = 0; i < d; i++) {
    int id = -1;
    int mx = -INF;
    for (int j = 0; j < 26; j++) {
      int res = nowscore(i, j);
      if (mx < res) {
        id = j;
        mx = res;
      }
    }
    solution[i] = id;
    last[id] = i + 1;
    llast[i][id] = true;
    myscore += mx;
  }

  clock_t end = clock();

  while (((double)(end - start) / CLOCKS_PER_SEC) < MX_SEC) {
    int k = day(mt);
    betterswap(k, min(k + num(mt), 365 - 1), start, end);
    better(day(mt), con(mt), start, end);
    end = clock();
  }

  rep(i, d) cout << solution[i] + 1 << endl;
  /*
  cout << myscore << endl;
  cout << (score(solution) + 1e6) << endl;
  cout << (myscore + 1e6) << endl;
  */

  return 0;
}