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

#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<int, int> P;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repi(i, a, b) for (int i = int(a); i < (b); i++)
#define repr(i, b, a) for (int i = int(b); i >= (a); i--)
#define all(x) x.begin(), x.end()

const ll mod = 1e9 + 7;
const ll INF = 1e9;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
bool valid(int lx, int ux, int ly, int uy, int x, int y) {
  return lx <= x && x < ux && ly <= y && y < uy;
}
ll power(ll x, ll p) {
  if (p == 0)
    return 1;
  ll res = power(x * x % mod, p / 2);
  if (p % 2 == 1)
    res = res * x % mod;
  return res;
}

int d, contest_num = 26;
vector<int> c(contest_num + 1, 0);
vector<vector<int>> s;
vector<set<int>> last(contest_num + 1);

void input() {
  cin >> d;
  s.resize(d + 1);
  rep(i, d + 1) { s[i].resize(contest_num + 1); }
  // rep(i,contest_num+1)last[i].resize(d+1,0);
  rep(i, 26) cin >> c[i + 1];
  rep(i, d) rep(j, contest_num) cin >> s[i + 1][j + 1];
}

void output(vector<int> &ans) { rep(i, d) cout << ans[i + 1] << endl; }

int max_lower_than_x(set<int> &st, int x) {
  int res = 0;
  for (auto tmp : st)
    if (tmp <= x)
      res = max(res, tmp);
  return res;
}

int min_upper_than_x(set<int> &st, int x) {
  int res = d + 1;
  for (auto tmp : st)
    if (tmp >= x)
      res = min(res, tmp);
  return res;
}

// b  AC
vector<int> calc_score(vector<int> &a) {
  vector<int> score(d + 1);
  int res = 0;
  repi(day, 1, d + 1) {
    int current_contest = a[day];
    last[current_contest].insert(day);

    res += s[day][current_contest];
    rep(i, contest_num) {
      res -= c[i + 1] * (day - max_lower_than_x(last[i + 1], day));
    }
    score[day] = res;
  }
  return score;
}

// c
int change_query(int score, int day, int before, int after) {
  int res = score;

  int before_prev = max_lower_than_x(last[before], day - 1);
  int before_next = min_upper_than_x(last[before], day + 1);

  int after_prev = max_lower_than_x(last[after], day - 1);
  int after_next = min_upper_than_x(last[after], day + 1);

  res -= (day - before_prev) * (before_next - day) * c[before];
  res -= s[day][before];

  res += (day - after_prev) * (after_next - day) * c[after];
  res += s[day][after];

  // last[before].erase(day);
  // last[after].insert(day);

  return res;
}

vector<int> random_schedule() {
  uint seed = 0;
  mt19937 engine(seed);
  uniform_real_distribution<> dist(0.0, 1.0);

  vector<int> res(d + 1, 0);
  rep(i, d) {
    int tmp = int(ceil(dist(engine) * contest_num));
    res[i + 1] = tmp;
  }
  return res;
}

int main() {
  input();
  rep(i, contest_num + 1) last[i].insert(0), last[i].insert(d + 1);
  vector<int> schedule = random_schedule();

  vector<int> days_score = calc_score(schedule);
  int score = days_score[d];

  chrono::system_clock::time_point start = chrono::system_clock::now();
  chrono::milliseconds time_limit{1980};

  uint seed = 0;
  mt19937 engine_day(seed), engine_contest(seed);
  uniform_int_distribution<> random_day(1, d), random_contest(1, contest_num);

  while (1) {
    auto now = chrono::system_clock::now();
    if (chrono::duration_cast<chrono::milliseconds>(now - start) > time_limit)
      break;

    int target_day = random_day(engine_day);
    int before = schedule[target_day];
    int after = random_contest(engine_contest);
    int score_next = change_query(score, target_day, before, after);
    if (score < score_next) {
      score = score_next;
      last[before].erase(target_day);
      last[after].insert(target_day);
      schedule[target_day] = after;
    }
  }

  output(schedule);

  return 0;
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<int, int> P;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repi(i, a, b) for (int i = int(a); i < (b); i++)
#define repr(i, b, a) for (int i = int(b); i >= (a); i--)
#define all(x) x.begin(), x.end()

const ll mod = 1e9 + 7;
const ll INF = 1e9;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
bool valid(int lx, int ux, int ly, int uy, int x, int y) {
  return lx <= x && x < ux && ly <= y && y < uy;
}
ll power(ll x, ll p) {
  if (p == 0)
    return 1;
  ll res = power(x * x % mod, p / 2);
  if (p % 2 == 1)
    res = res * x % mod;
  return res;
}

int d, contest_num = 26;
vector<int> c(contest_num + 1);
vector<vector<int>> s;
vector<set<int>> last(contest_num + 1);

void input() {
  cin >> d;
  s.resize(d + 1);
  rep(i, d + 1) { s[i].resize(contest_num + 1); }
  // rep(i,contest_num+1)last[i].resize(d+1,0);
  rep(i, 26) cin >> c[i + 1];
  rep(i, d) rep(j, contest_num) cin >> s[i + 1][j + 1];
}

void output(vector<int> &ans) { rep(i, d) cout << ans[i + 1] << endl; }

int max_lower_than_x(set<int> &st, int x) {
  int res = 0;
  for (auto tmp : st)
    if (tmp <= x)
      res = max(res, tmp);
  return res;
}

int min_upper_than_x(set<int> &st, int x) {
  int res = d + 1;
  for (auto tmp : st)
    if (tmp >= x)
      res = min(res, tmp);
  return res;
}

// b  AC
vector<int> calc_score(vector<int> &a) {
  vector<int> score(d + 1);
  int res = 0;
  repi(day, 1, d + 1) {
    int current_contest = a[day];
    last[current_contest].insert(day);

    res += s[day][current_contest];
    rep(i, contest_num) {
      res -= c[i + 1] * (day - max_lower_than_x(last[i + 1], day));
    }
    score[day] = res;
  }
  return score;
}

// c
int change_query(int score, int day, int before, int after) {
  int res = score;

  int before_prev = max_lower_than_x(last[before], day - 1);
  int before_next = min_upper_than_x(last[before], day + 1);

  int after_prev = max_lower_than_x(last[after], day - 1);
  int after_next = min_upper_than_x(last[after], day + 1);

  res -= (day - before_prev) * (before_next - day) * c[before];
  res -= s[day][before];

  res += (day - after_prev) * (after_next - day) * c[after];
  res += s[day][after];

  // last[before].erase(day);
  // last[after].insert(day);

  return res;
}

vector<int> random_schedule() {
  uint seed = 0;
  mt19937 engine(seed);
  uniform_real_distribution<> dist(0.0, 1.0);

  vector<int> res(d + 1, 0);
  rep(i, d) {
    int tmp = int(ceil(dist(engine) * d));
    res[i + 1] = tmp;
  }
  return res;
}

int main() {
  input();
  rep(i, contest_num + 1) last[i].insert(0), last[i].insert(d + 1);
  vector<int> schedule = random_schedule();

  vector<int> days_score = calc_score(schedule);
  int score = days_score[d];

  chrono::system_clock::time_point start = chrono::system_clock::now();
  chrono::milliseconds time_limit{1950};

  uint seed = 0;
  mt19937 engine_day(seed), engine_contest(seed);
  uniform_int_distribution<> random_day(1, d), random_contest(1, contest_num);

  while (1) {
    auto now = chrono::system_clock::now();
    if (chrono::duration_cast<chrono::milliseconds>(now - start) > time_limit)
      break;

    int target_day = random_day(engine_day);
    int before = schedule[target_day];
    int after = random_contest(engine_contest);
    int score_next = change_query(score, target_day, before, after);
    if (score < score_next) {
      score = score_next;
      last[before].erase(target_day);
      last[after].insert(target_day);
      schedule[target_day] = after;
    }
  }

  output(schedule);

  return 0;
}