Problem p02618 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#include <chrono>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
typedef int64_t Int;
typedef pair<Int, Int> P;

const Int Q = 26;

Int D;
vector<Int> C(Q);
vector<vector<Int>> S(400, vector<Int>(Q));

Int range(Int l, Int r) {
  Int len = r - l - 1;
  return -len * (len + 1) / 2;
}

//-------------------- 時間計測用 --------------------------
std::chrono::time_point<std::chrono::steady_clock> start;

void tic() { start = std::chrono::steady_clock::now(); }

double toc() {
  auto now = std::chrono::steady_clock::now();
  std::chrono::duration<double> duration = now - start;
  return duration.count();
}
//-----------------------------------------------------------

struct ContestInformation {
  vector<set<Int>> held; // held[q] : コンテストqを行った日程の集合
  vector<Int> schedule; // schedule[d]: d日目に実施するコンテストの番号
  Int score = 0;        // 最終日の満足度

  ContestInformation(Int D) {
    schedule.resize(D, 0);

    held.resize(Q);
    rep(q, Q) {
      held[q].insert(-1);
      held[q].insert(D);
    }
  }

  // scheduleを標準入力から読み込む
  void ReadSchedule() {
    rep(d, D) {
      Int q;
      cin >> q;
      q--;
      schedule[d] = q;
      held[q].insert(d);
    }
  }

  // scheduleの表示
  void OutputSchedule() { rep(d, D) cout << schedule[d] + 1 << endl; }

  // scheduleの貪欲法による初期化
  void InitSchedule() {
    Int score_now = 0;

    rep(d, D) {
      Int score_max = score_now;
      Int opt_q = -1;

      rep(q_now, Q) {
        Int score_next = score_now;
        schedule[d] = q_now;

        rep(q, Q) {
          if (q == q_now) {
            score_next += S[d][q];
          } else {
            auto itr_last_day = lower_bound(held[q].begin(), held[q].end(), d);
            score -= C[q] * (d - *prev(itr_last_day));
          }
        }

        if (score_next > score_max) {
          score_max = score_next;
          opt_q = q_now;
        }
      }

      schedule[d] = opt_q;
      held[opt_q].insert(d);
    }
  }

  // 最終日における満足度を計算する
  void CalcScore() {
    Int ans = 0;

    rep(d, D) {
      Int q_now = schedule[d]; // その日に行われるコンテスト

      rep(q, Q) {
        if (q == q_now) {
          ans += S[d][q];
        } else {
          auto itr_last_day = lower_bound(held[q].begin(), held[q].end(), d);
          ans -= C[q] * (d - *prev(itr_last_day));
        }
      }
    }

    score = ans;
  }

  // d日目をコンテストqに変更
  void modify(Int d, Int q_new) {

    // 元のコンテストの情報の削除
    Int q_old = schedule[d]; // 変更前のコンテスト
    score -= S[d][q_old];

    auto itr_old = held[q_old].find(d);
    auto r_old = next(itr_old);
    auto l_old = prev(itr_old);
    score += C[q_old] * range(*l_old, *r_old);
    score -= C[q_old] * range(*l_old, *itr_old);
    score -= C[q_old] * range(*itr_old, *r_old);

    held[q_old].erase(d);

    // 新しいコンテストの情報の追加
    score += S[d][q_new];
    held[q_new].insert(d);
    schedule[d] = q_new;

    auto itr_new = held[q_new].find(d);
    auto r_new = next(itr_new);
    auto l_new = prev(itr_new);
    score -= C[q_new] * range(*l_new, *r_new);
    score += C[q_new] * range(*l_new, *itr_new);
    score += C[q_new] * range(*itr_new, *r_new);
  }
};

int main() {
  cin >> D;
  rep(i, Q) cin >> C[i];
  rep(i, D) rep(j, Q) cin >> S[i][j];

  ContestInformation CI(D);
  tic();

  CI.InitSchedule();
  // CI.OutputSchedule();
  CI.CalcScore();

  while (toc() < 1.9) {
    Int old_score = CI.score;

    Int d = rand() % D;
    Int q_old = CI.schedule[d];
    Int q_new = rand() % 26;
    CI.modify(d, q_new);

    if (CI.score < old_score)
      CI.modify(d, q_old);
  }

  CI.OutputSchedule();
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>
#include <chrono>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
typedef int64_t Int;
typedef pair<Int, Int> P;

const Int Q = 26;

Int D;
vector<Int> C(Q);
vector<vector<Int>> S(400, vector<Int>(Q));

Int range(Int l, Int r) {
  Int len = r - l - 1;
  return -len * (len + 1) / 2;
}

//-------------------- 時間計測用 --------------------------
std::chrono::time_point<std::chrono::steady_clock> start;

void tic() { start = std::chrono::steady_clock::now(); }

double toc() {
  auto now = std::chrono::steady_clock::now();
  std::chrono::duration<double> duration = now - start;
  return duration.count();
}
//-----------------------------------------------------------

struct ContestInformation {
  vector<set<Int>> held; // held[q] : コンテストqを行った日程の集合
  vector<Int> schedule; // schedule[d]: d日目に実施するコンテストの番号
  Int score = 0;        // 最終日の満足度

  ContestInformation(Int D) {
    schedule.resize(D, 0);

    held.resize(Q);
    rep(q, Q) {
      held[q].insert(-1);
      held[q].insert(D);
    }
  }

  // scheduleを標準入力から読み込む
  void ReadSchedule() {
    rep(d, D) {
      Int q;
      cin >> q;
      q--;
      schedule[d] = q;
      held[q].insert(d);
    }
  }

  // scheduleの表示
  void OutputSchedule() { rep(d, D) cout << schedule[d] + 1 << endl; }

  // scheduleの初期化
  void InitSchedule() {
    rep(d, D) {
      Int max_score = -100000;
      Int opt_q = -1;

      rep(q, Q) {
        schedule[d] = q;
        CalcScore(d + 1);
        if (score > max_score) {
          max_score = score;
          opt_q = q;
        }
      }

      schedule[d] = opt_q;
      held[opt_q].insert(d);
    }
  }

  // day日目における満足度を計算する
  void CalcScore(int day) {
    Int ans = 0;

    rep(d, day) {
      Int q_now = schedule[d]; // その日に行われるコンテスト

      rep(q, Q) {
        if (q == q_now) {
          ans += S[d][q];
        } else {
          auto itr_last_day = lower_bound(held[q].begin(), held[q].end(), d);
          ans -= C[q] * (d - *prev(itr_last_day));
        }
      }
    }

    score = ans;
  }

  // d日目をコンテストqに変更
  void modify(Int d, Int q_new) {

    // 元のコンテストの情報の削除
    Int q_old = schedule[d]; // 変更前のコンテスト
    score -= S[d][q_old];

    auto itr_old = held[q_old].find(d);
    auto r_old = next(itr_old);
    auto l_old = prev(itr_old);
    score += C[q_old] * range(*l_old, *r_old);
    score -= C[q_old] * range(*l_old, *itr_old);
    score -= C[q_old] * range(*itr_old, *r_old);

    held[q_old].erase(d);

    // 新しいコンテストの情報の追加
    score += S[d][q_new];
    held[q_new].insert(d);
    schedule[d] = q_new;

    auto itr_new = held[q_new].find(d);
    auto r_new = next(itr_new);
    auto l_new = prev(itr_new);
    score -= C[q_new] * range(*l_new, *r_new);
    score += C[q_new] * range(*l_new, *itr_new);
    score += C[q_new] * range(*itr_new, *r_new);
  }
};

int main() {
  cin >> D;
  rep(i, Q) cin >> C[i];
  rep(i, D) rep(j, Q) cin >> S[i][j];

  ContestInformation CI(D);
  tic();

  CI.InitSchedule();
  // CI.OutputSchedule();
  CI.CalcScore(D);

  while (toc() < 1.9) {
    Int old_score = CI.score;

    Int d = rand() % D;
    Int q_old = CI.schedule[d];
    Int q_new = rand() % 26;
    CI.modify(d, q_new);

    if (CI.score < old_score)
      CI.modify(d, q_old);
  }

  CI.OutputSchedule();
}