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

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <time.h>
#include <vector>

using namespace std;
typedef long long ll;

int N = 26;
int D;
ll c[26];
ll s[366][36];
int t[366];
set<int> st[26];

random_device seed_gen;
default_random_engine engine(seed_gen());
uniform_real_distribution<> rand_dist(0.0, 1.0);

void input() {
  cin >> D;
  for (int i = 0; i < N; i++) {
    cin >> c[i];
    st[i].insert(0);
    st[i].insert(D + 1);
  }
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < N; j++)
      cin >> s[i][j];
  }
}

ll calc_score() {
  vector<int> last(N);
  ll S = 0;
  for (int d = 1; d <= D; d++) {
    last[t[d]] = d;
    for (int i = 0; i < N; i++) {
      S -= c[i] * (d - last[i]);
    }
    S += s[d][t[d]];
  }
  return S;
}

ll calc_change(ll prev, int d, int q) {
  prev -= s[d][t[d]];
  prev += s[d][q];
  // t[d]がなくなる
  {
    auto l = st[t[d]].find(d);
    l--;
    auto r = st[t[d]].upper_bound(d);
    ll dif_l = d - *l, dif_r = *r - d;
    prev -= (dif_l) * (dif_r)*c[t[d]];
  }
  // qが増える
  {
    auto l = st[q].lower_bound(d);
    l--;
    auto r = st[q].upper_bound(d);
    ll dif_l = d - *l, dif_r = *r - d;
    prev += (dif_l) * (dif_r)*c[q];
  }
  return prev;
}

void change(int d, int q) {
  st[t[d]].erase(d);
  st[q].insert(d);
  t[d] = q;
}

void output() {
  for (int i = 1; i <= D; i++)
    cout << t[i] + 1 << endl;
}

void make_random_ans() {
  for (int i = 1; i <= D; i++) {
    t[i] = rand() % N;
    st[t[i]].insert(i);
  }
}

double TIME_LIMIT = 1.5;

double p_th(double cur_time) {
  return 0.8 + (1.0 - 0.8) * (cur_time / TIME_LIMIT);
}

ll solve() {
  make_random_ans();
  clock_t start = clock();
  ll prev_sat = calc_score();
  int cnt = 0;
  while (true) {
    clock_t cur_time = clock();
    int d = (rand() % D) + 1, q = (rand() % N);
    ll cur_sat = calc_change(prev_sat, d, q);
    if (t[d] == q)
      continue;
    if (cur_sat > prev_sat) {
      prev_sat = cur_sat;
      change(d, q);
    } else {
      if (rand_dist(engine) >
          p_th((double)(cur_time - start) / CLOCKS_PER_SEC)) {
        change(d, q);
        prev_sat = cur_sat;
      }
    }
    if ((double)(cur_time - start) / CLOCKS_PER_SEC >= TIME_LIMIT)
      break;
  }
  return prev_sat;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << setprecision(10) << fixed;
  input();
  solve();
  output();
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <time.h>
#include <vector>

using namespace std;
typedef long long ll;

int N = 26;
int D;
ll c[26];
ll s[366][36];
int t[366];
set<int> st[26];

random_device seed_gen;
default_random_engine engine(seed_gen());
uniform_real_distribution<> rand_dist(0.0, 1.0);

void input() {
  cin >> D;
  for (int i = 0; i < N; i++) {
    cin >> c[i];
    st[i].insert(0);
    st[i].insert(D + 1);
  }
  for (int i = 1; i <= D; i++) {
    for (int j = 0; j < N; j++)
      cin >> s[i][j];
  }
}

ll calc_score() {
  vector<int> last(N);
  ll S = 0;
  for (int d = 1; d <= D; d++) {
    last[t[d]] = d;
    for (int i = 0; i < N; i++) {
      S -= c[i] * (d - last[i]);
    }
    S += s[d][t[d]];
  }
  return S;
}

ll calc_change(ll prev, int d, int q) {
  prev -= s[d][t[d]];
  prev += s[d][q];
  // t[d]がなくなる
  {
    auto l = st[t[d]].find(d);
    l--;
    auto r = st[t[d]].upper_bound(d);
    ll dif_l = d - *l, dif_r = *r - d;
    prev -= (dif_l) * (dif_r)*c[t[d]];
  }
  // qが増える
  {
    auto l = st[q].lower_bound(d);
    l--;
    auto r = st[q].upper_bound(d);
    ll dif_l = d - *l, dif_r = *r - d;
    prev += (dif_l) * (dif_r)*c[q];
  }
  return prev;
}

void change(int d, int q) {
  st[t[d]].erase(d);
  st[q].insert(d);
  t[d] = q;
}

void output() {
  for (int i = 1; i <= D; i++)
    cout << t[i] + 1 << endl;
}

void make_random_ans() {
  for (int i = 1; i <= D; i++) {
    t[i] = rand() % N;
  }
}

double TIME_LIMIT = 1.5;

double p_th(double cur_time) { 0.5 + (1.0 - 0.5) * (cur_time / TIME_LIMIT); }

ll solve() {
  make_random_ans();
  clock_t start = clock();
  ll prev_sat = calc_score();
  while (true) {
    clock_t cur_time = clock();
    int d = (rand() % D) + 1, q = (rand() % N);
    ll cur_sat = calc_change(prev_sat, d, q);
    if (cur_sat > prev_sat) {
      prev_sat = cur_sat;
      change(d, q);
    } else {
      if (rand_dist(engine) > p_th((double)(cur_time - start) / CLOCKS_PER_SEC))
        change(d, q);
    }
    if ((double)(cur_time - start) / CLOCKS_PER_SEC >= TIME_LIMIT)
      break;
  }
  return prev_sat;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << setprecision(10) << fixed;
  input();
  solve();
  output();
}