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

#include <bits/stdc++.h>
using namespace std;

int main() {
  srand(0);

  // input
  constexpr int n = 26;
  int d;
  cin >> d;
  vector<int> c(n);
  for (auto &e : c)
    cin >> e;
  vector<vector<int>> s(d, vector<int>(n));
  for (auto &se : s) {
    for (auto &e : se)
      cin >> e;
  }

  // solve
  int satisfaction = 0;
  vector<set<int>> v(n);
  for (auto &e : v)
    e.insert(-1);
  vector<int> t(d);
  for (int i = 0; i < d; i++) {
    t[i] = max_element(s[i].begin(), s[i].end()) - s[i].begin();
    satisfaction += s[i][t[i]];
    v[t[i]].insert(i);

    for (int j = 0; j < n; j++) {
      int last_i = *v[j].rbegin();
      satisfaction -= c[j] * (i - last_i);
    }
  }

  auto calculate_decline = [](int c, int d) { return -c * ((d - 1) * d / 2); };

  auto calculate_difference = [&](int i, int j) {
    int difference = 0;
    difference -= s[i][t[i]];
    difference += s[i][j];

    auto it1_to = v[t[i]].upper_bound(i);
    auto it1_from = it1_to;
    it1_from--;
    it1_from--;
    int i1_to = it1_to == v[t[i]].end() ? d : *it1_to, i1_from = *it1_from;

    auto it2_to = v[j].upper_bound(i);
    auto it2_from = it2_to;
    it2_from--;
    int i2_to = it2_to == v[j].end() ? d : *it2_to, i2_from = *it2_from;

    difference -= calculate_decline(c[t[i]], i - i1_from) +
                  calculate_decline(c[t[i]], i1_to - i);
    difference += calculate_decline(c[t[i]], i1_to - i1_from);

    difference -= calculate_decline(c[j], i2_to - i2_from);
    difference += calculate_decline(c[j], i - i2_from) +
                  calculate_decline(c[j], i2_to - i);

    return difference;
  };

  for (int iteration = 0; iteration < (int)1e7; iteration++) {
    if (rand() % 2) {
      int i = rand() % d, j = rand() % n;
      if (t[i] == j)
        continue;

      int difference = 0;
      difference += calculate_difference(i, j);

      if (difference > 0) {
        satisfaction += difference;
        v[t[i]].erase(i);
        v[j].insert(i);
        t[i] = j;
      }
    } else {
      int i = rand() % (d - 1);
      if (t[i] == t[i + 1])
        continue;

      int difference = 0;
      difference += calculate_difference(i, t[i + 1]);
      difference += calculate_difference(i + 1, t[i]);

      if (difference > 0) {
        satisfaction += difference;
        v[t[i]].erase(i);
        v[t[i]].insert(i + 1);
        v[t[i + 1]].erase(i + 1);
        v[t[i + 1]].insert(i);
        swap(t[i], t[i + 1]);
      }
    }
  }

  // output
  cerr << "satisfaction: " << satisfaction << endl;
  cerr << "score: " << max((int)1e6 + satisfaction, 0) << endl;

  for (auto e : t)
    cout << e + 1 << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int decline(int c, int d) { return -c * ((d - 1) * d / 2); }

int main() {
  srand(0);

  constexpr int n = 26;
  int d;
  cin >> d;
  vector<int> c(n);
  for (auto &e : c)
    cin >> e;
  vector<vector<int>> s(d, vector<int>(n));
  for (auto &se : s) {
    for (auto &e : se)
      cin >> e;
  }

  int best_satisfaction = 0;
  vector<int> best_t(d);

  for (int iteration = 0; iteration < (int)1e3; iteration++) {
    int satisfaction = 0;
    vector<set<int>> v(n);
    for (auto &e : v)
      e.insert(-1);
    vector<int> t(d);
    for (int i = 0; i < d; i++) {
      t[i] = iteration == 0
                 ? max_element(s[i].begin(), s[i].end()) - s[i].begin()
                 : rand() % n;
      satisfaction += s[i][t[i]];
      v[t[i]].insert(i);

      for (int j = 0; j < n; j++) {
        int last_i = *v[j].rbegin();
        satisfaction -= c[j] * (i - last_i);
      }
    }

    for (int climbing_iteration = 0; climbing_iteration < (int)1e5;
         climbing_iteration++) {
      int i = rand() % d, j = rand() % n;
      if (t[i] == j)
        continue;

      int difference = 0;
      difference -= s[i][t[i]];
      difference += s[i][j];

      auto it1_to = v[t[i]].upper_bound(i);
      auto it1_from = it1_to;
      it1_from--;
      it1_from--;
      int i1_to = it1_to == v[t[i]].end() ? d : *it1_to, i1_from = *it1_from;

      auto it2_to = v[j].upper_bound(i);
      auto it2_from = it2_to;
      it2_from--;
      int i2_to = it2_to == v[j].end() ? d : *it2_to, i2_from = *it2_from;

      difference -= decline(c[t[i]], i - i1_from) + decline(c[t[i]], i1_to - i);
      difference += decline(c[t[i]], i1_to - i1_from);

      difference -= decline(c[j], i2_to - i2_from);
      difference += decline(c[j], i - i2_from) + decline(c[j], i2_to - i);

      if (difference > 0) {
        satisfaction += difference;
        v[t[i]].erase(i);
        v[j].insert(i);
        t[i] = j;
      }

      // cerr << i << ' ' << j << endl;
      // cerr << i1_from << ' ' << i1_to << ' ' << i2_from << ' ' << i2_to <<
      // endl; cerr << difference << endl;
    }

    if (satisfaction > best_satisfaction) {
      best_satisfaction = satisfaction;
      best_t = t;
    }
  }

  cerr << "satisfaction: " << best_satisfaction << endl;
  cerr << "score: " << max((int)1e6 + best_satisfaction, 0) << endl;

  for (auto e : best_t)
    cout << e + 1 << endl;
}