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

#include <algorithm>
#include <chrono>
#include <cstring>
#include <ctime>
#include <iostream>
#include <random>
#include <set>
#include <vector>
using namespace std;
using ll = long long int;

const int C_NUM = 26;
const int D_MAX = 366;
int D;
int c[C_NUM + 5];
int s[D_MAX][C_NUM + 5];

int t[D_MAX];
set<int> last[C_NUM + 5];

int main() {
  chrono::system_clock::time_point start, end;
  start = chrono::system_clock::now();
  cin >> D;
  for (int i = 1; i <= C_NUM; i++)
    cin >> c[i];
  for (int i = 1; i <= D; i++) {
    for (int j = 1; j <= C_NUM; j++) {
      cin >> s[i][j];
    }
  }
  ll v = 0;
  for (int j = 1; j <= C_NUM; j++)
    last[j].insert(0);
  for (int i = 1; i <= D; i++) {
    ll merit = 0;
    int choice = 0;
    for (int j = 1; j <= C_NUM; j++) {
      ll nowm = s[i][j];
      nowm += c[j] * (i - *last[j].rbegin());
      if (nowm > merit) {
        merit = nowm;
        choice = j;
      }
    }
    v += merit;
    last[choice].insert(i);
    t[i] = choice;
  }

  for (int j = 1; j <= C_NUM; j++)
    last[j].insert(D + 1);
  random_device rnd;
  int count = 0;
  end = chrono::system_clock::now();
  double ttime = static_cast<double>(
      chrono::duration_cast<chrono::microseconds>(end - start).count() /
      1000.0);
  while (count < 100000) {
    int sub = 0;
    int day = (rnd() % D) + 1;
    int o = t[day];
    int nowmax = 0;
    int choice = o;
    for (int n = 1; n <= C_NUM; n++) {
      if (n == o)
        continue;
      sub = s[day][n] - s[day][o];
      int bo = *(--last[o].find(day));
      int ao = *(++last[o].find(day));
      sub -= c[o] * (day - bo) * (ao - day);
      last[n].insert(day);
      int bn = *(--last[n].find(day));
      int an = *(++last[n].find(day));
      sub += c[n] * (day - bn) * (an - day);
      if (nowmax < sub) {
        nowmax = sub;
        choice = n;
      }
      last[n].erase(day);
    }
    v += nowmax;
    t[day] = choice;
    last[o].erase(day);
    last[choice].insert(day);
    end = chrono::system_clock::now();
    double ttime = static_cast<double>(
        chrono::duration_cast<chrono::microseconds>(end - start).count() /
        1000.0);
    count++;
  }
  for (int i = 1; i <= D; i++)
    cout << t[i] << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <chrono>
#include <cstring>
#include <ctime>
#include <iostream>
#include <random>
#include <set>
#include <vector>
using namespace std;
using ll = long long int;

const int C_NUM = 26;
const int D_MAX = 366;
int D;
int c[C_NUM + 5];
int s[D_MAX][C_NUM + 5];

int t[D_MAX];
set<int> last[C_NUM + 5];

int main() {
  chrono::system_clock::time_point start, end;
  start = chrono::system_clock::now();
  cin >> D;
  for (int i = 1; i <= C_NUM; i++)
    cin >> c[i];
  for (int i = 1; i <= D; i++) {
    for (int j = 1; j <= C_NUM; j++) {
      cin >> s[i][j];
    }
  }

  for (int j = 1; j <= C_NUM; j++)
    last[j].insert(0);
  for (int i = 1; i <= D; i++) {
    ll merit = 0;
    int choice = 1;
    for (int j = 1; j <= C_NUM; j++) {
      ll nowm = s[i][j];
      nowm += c[j] * (i - *last[j].rbegin());
      if (nowm > merit) {
        merit = nowm;
        choice = j;
      }
    }
    last[choice].insert(i);
    t[i] = choice;
  }
  for (int j = 1; j <= C_NUM; j++)
    last[j].insert(D + 1);
  random_device rnd;
  end = chrono::system_clock::now();
  double time = static_cast<double>(
      chrono::duration_cast<chrono::microseconds>(end - start).count() /
      1000.0);
  while (time < 1900) {
    int sub;
    int day = (rnd() % D) + 1;
    int o = t[day];
    int nowmax = 0;
    int choice = o;
    for (int n = 1; n <= C_NUM; n++) {
      if (n == o)
        continue;
      sub = s[day][n] - s[day][o];
      int bo = *(--last[o].find(day));
      int ao = *(++last[o].find(day));
      sub -= c[o] * (day - bo) * (ao - day);
      last[o].erase(day);
      last[n].insert(day);
      int bn = *(--last[n].find(day));
      int an = *(++last[n].find(day));
      sub += c[n] * (day - bn) * (an - day);
      if (nowmax < sub) {
        nowmax = sub;
        choice = n;
      }
    }
    t[day] = choice;
    end = chrono::system_clock::now();
    double time = static_cast<double>(
        chrono::duration_cast<chrono::microseconds>(end - start).count() /
        1000.0);
  }
  for (int i = 1; i <= D; i++)
    cout << t[i] << endl;
  return 0;
}