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

#include <bits/stdc++.h>
#include <chrono>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1000000007
using namespace std;
random_device rd{};

void init_yotei_and_last(long *yotei, long *last, long d, long n) {
  rep(i, d) yotei[i] = rd() % n;
  rep(i, n) last[i] = 0;
}

int change_yotei(long *days, long *yotei, long *pre_cons, long n, long d,
                 long ii) {
  vector<bool> flag(d, false);
  long new_con;
  int change_num = (100050 - ii) / 2000 + 1;
  rep(i, change_num) {
    while (1) {
      int day = rd() % d;
      if (flag[day] == false) {
        days[i] = day;
        flag[day] = true;
        break;
      }
    }
    while (1) {
      new_con = rd() % n;
      if (yotei[days[i]] != new_con) {
        pre_cons[i] = yotei[days[i]];
        yotei[days[i]] = new_con;
        break;
      }
    }
  }
  return change_num;
}

int main() {
  chrono::system_clock::time_point start, end;
  start = chrono::system_clock::now();
  long d;
  cin >> d;
  long n = 26, csum = 0, ccost = 0;
  long c[n];
  rep(i, n) {
    cin >> c[i];
    csum += c[i];
  }
  long s[d][n];
  rep(i, d) rep(j, n) cin >> s[i][j];
  vector<vector<long>> cand;
  vector<long> tmp(d);
  long yotei[d];
  long final_ans = 0, final_index = 0;
  long last[n];

  rep(jj, 20) {
    long ans = 0;
    init_yotei_and_last(yotei, last, d, n);
    rep(i, d) {
      ccost += csum;
      ccost -= c[yotei[i]] * (i + 1 - last[yotei[i]]);
      ans -= ccost;
      last[yotei[i]] = i + 1;
      ans += s[i][yotei[i]];
    }
    int ii = 0;
    long days[60], pre_cons[60];
    while (ii < 100000) {
      int change_num = change_yotei(days, yotei, pre_cons, n, d, ii);
      long tmpans = 0;
      ccost = 0;
      rep(i, n) last[i] = 0;
      rep(i, d) {
        tmp[i] = yotei[i];
        ccost += csum;
        ccost -= c[yotei[i]] * (i + 1 - last[yotei[i]]);
        tmpans -= ccost;
        last[yotei[i]] = i + 1;
        tmpans += s[i][yotei[i]];
      }
      if (tmpans < ans) {
        rep(i, change_num) yotei[days[i]] = pre_cons[i];
      } else {
        ans = tmpans;
        cand.push_back(tmp);
      }
      ii++;
    }
    if (final_ans < ans) {
      final_ans = ans;
      final_index = int(cand.size() - 1);
    }
    end = chrono::system_clock::now();
    auto time = end - start;
    if (static_cast<double>(
            chrono::duration_cast<chrono::milliseconds>(time).count()) > 1000)
      break;
  }
  rep(i, d) cout << cand[final_index][i] + 1 << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <chrono>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1000000007
using namespace std;
random_device rd{};

void init_yotei_and_last(long *yotei, long *last, long d, long n) {
  rep(i, d) yotei[i] = rd() % n;
  rep(i, n) last[i] = 0;
}

int change_yotei(long *days, long *yotei, long *pre_cons, long n, long d,
                 long ii) {
  vector<bool> flag(d, false);
  long new_con;
  int change_num = (100050 - ii) / 2000 + 1;
  rep(i, change_num) {
    while (1) {
      int day = rd() % d;
      if (flag[day] == false) {
        days[i] = day;
        flag[day] = true;
        break;
      }
    }
    while (1) {
      new_con = rd() % n;
      if (yotei[days[i]] != new_con) {
        pre_cons[i] = yotei[days[i]];
        yotei[days[i]] = new_con;
        break;
      }
    }
  }
  return change_num;
}

int main() {
  chrono::system_clock::time_point start, end;
  start = chrono::system_clock::now();
  long d;
  cin >> d;
  long n = 26, csum = 0, ccost = 0;
  long c[n];
  rep(i, n) {
    cin >> c[i];
    csum += c[i];
  }
  long s[d][n];
  rep(i, d) rep(j, n) cin >> s[i][j];
  vector<vector<long>> cand;
  vector<long> tmp(d);
  long yotei[d];
  long final_ans = 0, final_index;
  long last[n];

  rep(jj, 20) {
    long ans = 0;
    init_yotei_and_last(yotei, last, d, n);
    rep(i, d) {
      ccost += csum;
      ccost -= c[yotei[i]] * (i + 1 - last[yotei[i]]);
      ans -= ccost;
      last[yotei[i]] = i + 1;
      ans += s[i][yotei[i]];
    }
    int ii = 0;
    long days[60], pre_cons[60];
    while (ii < 100000) {
      int change_num = change_yotei(days, yotei, pre_cons, n, d, ii);
      long tmpans = 0;
      ccost = 0;
      rep(i, n) last[i] = 0;
      rep(i, d) {
        tmp[i] = yotei[i];
        ccost += csum;
        ccost -= c[yotei[i]] * (i + 1 - last[yotei[i]]);
        tmpans -= ccost;
        last[yotei[i]] = i + 1;
        tmpans += s[i][yotei[i]];
      }
      if (tmpans < ans) {
        rep(i, change_num) yotei[days[i]] = pre_cons[i];
      } else {
        ans = tmpans;
        cand.push_back(tmp);
      }
      ii++;
    }
    if (final_ans < ans) {
      final_ans = ans;
      final_index = int(cand.size() - 1);
    }
    end = chrono::system_clock::now();
    auto time = end - start;
    if (static_cast<double>(
            chrono::duration_cast<chrono::milliseconds>(time).count()) > 1880)
      break;
  }
  rep(i, d) cout << cand[final_index][i] + 1 << endl;
  return 0;
}