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

#include <bits/stdc++.h>
#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> T div_floor(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T> T div_ceil(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1e9 + 7;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

int D, contests[370], ans[370];
lint c[30], s[370][30];
set<int> held_days[30];
lint best_score;

lint get_score(int dd) {
  For(i, 1, 27) {
    held_days[i].clear();
    held_days[i].insert(0);
    held_days[i].insert(D + 1);
  }
  lint ret = 0;
  For(day, 1, dd + 1) {
    For(i, 1, 27) {
      if (contests[day] == i) {
        ret += s[day][i];
        held_days[i].insert(day);
      } else
        ret -= c[i] * (day - *next(held_days[i].rbegin()));
    }
  }
  return ret;
}

lint fsum(int n) { return n * (n + 1) / 2; }

lint score_diff(int day, int idx) {
  lint ret = 0;
  int prev_id = contests[day];
  contests[day] = idx;

  ret += s[day][idx];
  auto r = held_days[idx].lower_bound(day), l = prev(r);
  ret += c[idx] * fsum(*r - 1 - *l);
  ret -= c[idx] * (fsum(day - 1 - *l) + fsum(*r - 1 - day));
  held_days[idx].insert(day);

  ret -= s[day][prev_id];
  auto m = held_days[prev_id].find(day);
  r = next(m);
  l = prev(m);
  ret += c[prev_id] * (fsum(day - 1 - *l) + fsum(*r - 1 - day));
  ret -= c[prev_id] * fsum(*r - 1 - *l);
  held_days[prev_id].erase(day);

  return ret;
}

void input() {
  scanf("%d", &D);
  For(i, 1, 27) scanf("%lld", &c[i]);
  For(i, 1, D + 1) For(j, 1, 27) scanf("%lld", &s[i][j]);
}

void output() { For(i, 1, D + 1) printf("%d\\n", ans[i]); }

int main() {
  input();

  For(day, 1, D + 1) {
    int idx;
    lint max_score = -INF;
    For(i, 1, 27) {
      contests[day] = i;
      if (chmax(max_score, get_score(day)))
        idx = i;
    }
    contests[day] = idx;
  }

  double temperature = 100000, colding_rate = 0.99999;
  lint score = get_score(D);
  best_score = score;
  random_device rd;
  mt19937 mt(rd());
  uniform_real_distribution<> dist(0.0, 1.0);
  clock_t start = clock();
  while ((clock() - start) / CLOCKS_PER_SEC < 1.0) {
    int day = mt() % D + 1;
    int idx = mt() % 26 + 1;
    int prev_id = contests[day];
    lint diff = score_diff(day, idx);

    if (diff > 0)
      score += diff;
    else {
      double prob = dist(mt);
      if (prob <= exp(diff / temperature))
        score += diff;
      else
        score_diff(day, prev_id);
    }

    if (chmax(best_score, score)) {
      For(i, 1, D + 1) ans[i] = contests[i];
    }

    temperature *= colding_rate;
  }

  output();
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> T div_floor(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T> T div_ceil(T a, T b) {
  if (b < 0)
    a *= -1, b *= -1;
  return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1e9 + 7;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

int D, contests[370], ans[370];
lint c[30], s[370][30];
set<int> held_days[30];
lint best_score;

lint get_score(int dd) {
  For(i, 1, 27) {
    held_days[i].clear();
    held_days[i].insert(0);
    held_days[i].insert(D + 1);
  }
  lint ret = 0;
  For(day, 1, dd + 1) {
    For(i, 1, 27) {
      if (contests[day] == i) {
        ret += s[day][i];
        held_days[i].insert(day);
      } else
        ret -= c[i] * (day - *next(held_days[i].rbegin()));
    }
  }
  return ret;
}

lint fsum(int n) { return n * (n + 1) / 2; }

lint score_diff(int day, int idx) {
  lint ret = 0;
  int prev_id = contests[day];
  contests[day] = idx;

  ret += s[day][idx];
  auto r = held_days[idx].lower_bound(day), l = prev(r);
  ret += c[idx] * fsum(*r - 1 - *l);
  ret -= c[idx] * (fsum(day - 1 - *l) + fsum(*r - 1 - day));
  held_days[idx].insert(day);

  ret -= s[day][prev_id];
  auto m = held_days[prev_id].find(day);
  r = next(m);
  l = prev(m);
  ret += c[prev_id] * (fsum(day - 1 - *l) + fsum(*r - 1 - day));
  ret -= c[prev_id] * fsum(*r - 1 - *l);
  held_days[prev_id].erase(day);

  return ret;
}

void input() {
  scanf("%d", &D);
  For(i, 1, 27) scanf("%lld", &c[i]);
  For(i, 1, D + 1) For(j, 1, 27) scanf("%lld", &s[i][j]);
}

void output() { For(i, 1, D + 1) printf("%d\\n", ans[i]); }

int main() {
  input();

  For(i, 1, D + 1) ans[i] = contests[i] = i % 26 + 1;

  double temperature = 100000, colding_rate = 0.99999;
  lint score = get_score(D);
  best_score = score;
  random_device rd;
  mt19937 mt(rd());
  uniform_real_distribution<> dist(0.0, 1.0);
  clock_t start = clock();
  while ((clock() - start) / CLOCKS_PER_SEC < 1.2) {
    int day = mt() % D + 1;
    int idx = mt() % 26 + 1;
    int prev_id = contests[day];
    lint diff = score_diff(day, idx);

    if (diff > 0)
      score += diff;
    else {
      double prob = dist(mt);
      if (prob <= exp(diff / temperature))
        score += diff;
      else
        score_diff(day, prev_id);
    }

    if (chmax(best_score, score)) {
      For(i, 1, D + 1) ans[i] = contests[i];
    }

    temperature *= colding_rate;
  }

  output();
}