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

#include <bits/stdc++.h>

using namespace std;

class xor_shift_128 {
public:
  typedef uint32_t result_type;
  explicit xor_shift_128(uint32_t seed = 42) { set_seed(seed); }
  void set_seed(uint32_t seed) {
    a = seed = 1812433253u * (seed ^ (seed >> 30));
    b = seed = 1812433253u * (seed ^ (seed >> 30)) + 1;
    c = seed = 1812433253u * (seed ^ (seed >> 30)) + 2;
    d = seed = 1812433253u * (seed ^ (seed >> 30)) + 3;
  }
  uint32_t operator()() {
    uint32_t t = (a ^ (a << 11));
    a = b;
    b = c;
    c = d;
    return d = (d ^ (d >> 19)) ^ (t ^ (t >> 8));
  }
  static constexpr uint32_t max() { return numeric_limits<result_type>::max(); }
  static constexpr uint32_t min() { return numeric_limits<result_type>::min(); }

private:
  uint32_t a{}, b{}, c{}, d{};
};

const int CONTEST_NUM = 26;

struct State {
  vector<int> contest_order;
  State(const int D) : contest_order(vector<int>(D + 1)) {}
};

template <class Generator>
int choose(int const min, int const max, Generator &gen) {
  assert(min <= max);
  return uniform_int_distribution<int>(min, max)(gen);
}

long long compute_score(const State &state, const vector<int> &costs,
                        const vector<vector<int>> &values, const int D) {
  long long score = 0;
  vector<int> last(CONTEST_NUM + 1, 0);
  for (int i = 1; i <= D; i++) {
    score += values[i][state.contest_order[i]];
    last[state.contest_order[i]] = i;
    for (int j = 1; j <= CONTEST_NUM; j++) {
      score -= costs[i] * (i - last[j]);
    }
  }
  return score;
}

template <class Generator>
State solve(const vector<int> &costs, const vector<vector<int>> &values,
            const int D, Generator &gen) {
  State best_state(D), state(D);

  if (getenv("RESUME")) {
    ifstream ifs(getenv("RESUME"));
    string line;
    getline(ifs, line);
    int cnt = 0;
    while (getline(ifs, line)) {
      cnt++;
      if (cnt % 2 == 0)
        continue;
      stringstream ss_line(line);
    }
  } else { // make an initial state
    vector<int> last(CONTEST_NUM + 1, 0);
    for (int i = 1; i <= D; i++) {
      long long maxDiff = LLONG_MIN, contestId = -1;
      for (int j = 1; j <= CONTEST_NUM; j++) {
        long long diff = values[i][j];
        for (int k = 1; k <= CONTEST_NUM; k++) {
          if (k == j)
            continue;
          diff -= costs[i] * (i - last[k]);
        }
        if (diff > maxDiff) {
          maxDiff = diff;
          contestId = j;
        }
      }
      assert(contestId != -1);
      state.contest_order[i] = contestId;
      last[state.contest_order[i]] = i;
    }
  }

  best_state = state;
  long long score = compute_score(state, costs, values, D);
  long long highscore = score;
  //    cerr << "[*] highscore = " << highscore << endl;

  //    constexpr int TIME_LIMIT = 1000;  // msec
  //    chrono::high_resolution_clock::time_point clock_begin =
  //    chrono::high_resolution_clock::now(); double temperature = 1; for
  //    (unsigned iteration = 0; ; ++ iteration) {
  //        if (iteration % 128 == 0) {
  //            chrono::high_resolution_clock::time_point clock_end =
  //            chrono::high_resolution_clock::now(); temperature = 1 -
  //            chrono::duration_cast<chrono::milliseconds>(clock_end -
  //            clock_begin).count() / TIME_LIMIT; if (temperature < 0) {
  ////                cerr << "[*] iteration = " << iteration << ": done" <<
  ///endl;
  //                break;
  //            }
  //        }
  //
  //        const int newContestId = choose(1, CONTEST_NUM, gen);
  //        const int day = choose(1, D, gen);
  //        const int oldContestId = state.contest_order[day];
  //        state.contest_order[day] = newContestId;
  //
  //        long long newScore = compute_score(state, costs, values, D);
  //        long long delta = newScore - score;
  //
  //        constexpr double boltzmann = 3;
  //        if (delta >= 0 or bernoulli_distribution(exp(boltzmann * delta) *
  //        temperature)(gen)) {
  //            if (delta < 0) {
  ////                cerr << "[*] iteration = " << iteration << ": delta = " <<
  ///delta << ": p = " << exp(boltzmann * delta) * temperature << endl;
  //            }
  //            score += delta;
  //            if (highscore < score) {
  //                highscore = score;
  //                best_state = state;
  ////                cerr << "[*] iteration = " << iteration << ": highscore =
  ///" << highscore << endl;
  //            }
  //        } else {
  //            // resume
  //            state.contest_order[day] = oldContestId;
  //        }
  //    }

  //    cerr << "[*] highscore = " << highscore << endl;

  return best_state;
}

int main() {
  int D;
  scanf("%lld", &D);
  std::vector<int> c(CONTEST_NUM + 1);
  for (int i = 1; i <= 26; i++) {
    scanf("%lld", &c[i]);
  }
  std::vector<std::vector<int>> s(D + 1, std::vector<int>(CONTEST_NUM + 1));
  for (int i = 1; i <= D; i++) {
    for (int j = 1; j <= 26; j++) {
      scanf("%lld", &s[i][j]);
    }
  }

  // solve
  xor_shift_128 gen;
  State state = solve(std::move(c), std::move(s), D, gen);

  // output
  stringstream ss;
  int cnt = 0;
  for (int i = 1; i <= D; i++) {
    ss << state.contest_order[i] << "\\n";
  }
  cout << ss.str();
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

class xor_shift_128 {
public:
  typedef uint32_t result_type;
  explicit xor_shift_128(uint32_t seed = 42) { set_seed(seed); }
  void set_seed(uint32_t seed) {
    a = seed = 1812433253u * (seed ^ (seed >> 30));
    b = seed = 1812433253u * (seed ^ (seed >> 30)) + 1;
    c = seed = 1812433253u * (seed ^ (seed >> 30)) + 2;
    d = seed = 1812433253u * (seed ^ (seed >> 30)) + 3;
  }
  uint32_t operator()() {
    uint32_t t = (a ^ (a << 11));
    a = b;
    b = c;
    c = d;
    return d = (d ^ (d >> 19)) ^ (t ^ (t >> 8));
  }
  static constexpr uint32_t max() { return numeric_limits<result_type>::max(); }
  static constexpr uint32_t min() { return numeric_limits<result_type>::min(); }

private:
  uint32_t a{}, b{}, c{}, d{};
};

const int CONTEST_NUM = 26;

struct State {
  vector<int> contest_order;
  State(const int D) : contest_order(vector<int>(D + 1)) {}
};

template <class Generator>
int choose(int const min, int const max, Generator &gen) {
  assert(min <= max);
  return uniform_int_distribution<int>(min, max)(gen);
}

long long compute_score(const State &state, const vector<int> &costs,
                        const vector<vector<int>> &values, const int D) {
  long long score = 0;
  vector<int> last(CONTEST_NUM + 1, 0);
  for (int i = 1; i <= D; i++) {
    score += values[i][state.contest_order[i]];
    last[state.contest_order[i]] = i;
    for (int j = 1; j <= CONTEST_NUM; j++) {
      score -= costs[i] * (i - last[j]);
    }
  }
  return score;
}

template <class Generator>
State solve(const vector<int> &costs, const vector<vector<int>> &values,
            const int D, Generator &gen) {
  State best_state(D), state(D);

  if (getenv("RESUME")) {
    ifstream ifs(getenv("RESUME"));
    string line;
    getline(ifs, line);
    int cnt = 0;
    while (getline(ifs, line)) {
      cnt++;
      if (cnt % 2 == 0)
        continue;
      stringstream ss_line(line);
    }
  } else { // make an initial state
    vector<int> last(CONTEST_NUM + 1, 0);
    for (int i = 1; i <= D; i++) {
      long long maxDiff = LLONG_MIN, contestId = -1;
      for (int j = 1; j <= CONTEST_NUM; j++) {
        long long diff = values[i][j];
        for (int k = 1; k <= CONTEST_NUM; k++) {
          if (k == j)
            continue;
          diff -= costs[i] * (i - last[k]);
        }
        if (diff > maxDiff) {
          maxDiff = diff;
          contestId = j;
        }
      }
      assert(contestId != -1);
      state.contest_order[i] = contestId;
      last[state.contest_order[i]] = i;
    }
  }

  best_state = state;
  long long score = compute_score(state, costs, values, D);
  long long highscore = score;
  //    cerr << "[*] highscore = " << highscore << endl;

  constexpr int TIME_LIMIT = 1000; // msec
  chrono::high_resolution_clock::time_point clock_begin =
      chrono::high_resolution_clock::now();
  double temperature = 1;
  for (unsigned iteration = 0;; ++iteration) {
    if (iteration % 128 == 0) {
      chrono::high_resolution_clock::time_point clock_end =
          chrono::high_resolution_clock::now();
      temperature = 1 - chrono::duration_cast<chrono::milliseconds>(clock_end -
                                                                    clock_begin)
                                .count() /
                            TIME_LIMIT;
      if (temperature < 0) {
        //                cerr << "[*] iteration = " << iteration << ": done" <<
        //                endl;
        break;
      }
    }

    const int newContestId = choose(1, CONTEST_NUM, gen);
    const int day = choose(1, D, gen);
    const int oldContestId = state.contest_order[day];
    state.contest_order[day] = newContestId;

    long long newScore = compute_score(state, costs, values, D);
    long long delta = newScore - score;

    constexpr double boltzmann = 3;
    if (delta >= 0 or
        bernoulli_distribution(exp(boltzmann * delta) * temperature)(gen)) {
      if (delta < 0) {
        //                cerr << "[*] iteration = " << iteration << ": delta =
        //                " << delta << ": p = " << exp(boltzmann * delta) *
        //                temperature << endl;
      }
      score += delta;
      if (highscore < score) {
        highscore = score;
        best_state = state;
        //                cerr << "[*] iteration = " << iteration << ":
        //                highscore = " << highscore << endl;
      }
    } else {
      // resume
      state.contest_order[day] = oldContestId;
    }
  }

  //    cerr << "[*] highscore = " << highscore << endl;

  return best_state;
}

int main() {
  int D;
  scanf("%lld", &D);
  std::vector<int> c(CONTEST_NUM + 1);
  for (int i = 1; i <= 26; i++) {
    scanf("%lld", &c[i]);
  }
  std::vector<std::vector<int>> s(D + 1, std::vector<int>(CONTEST_NUM + 1));
  for (int i = 1; i <= D; i++) {
    for (int j = 1; j <= 26; j++) {
      scanf("%lld", &s[i][j]);
    }
  }

  // solve
  xor_shift_128 gen;
  State state = solve(std::move(c), std::move(s), D, gen);

  // output
  stringstream ss;
  int cnt = 0;
  for (int i = 1; i <= D; i++) {
    ss << state.contest_order[i] << "\\n";
  }
  cout << ss.str();
  return 0;
}