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

#include <cassert>
#include <iostream>
#include <random>
#include <string>
#include <vector>
#define rep(i, start, end) for (int i = (int)start; i < (int)end; ++i)
#define rrep(i, start, end) for (int i = (int)start - 1; i >= (int)end; --i)
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return 0;
}

const int INF = 1 << 30;
const int MAX_ITR = 100000;

int calcScore(int D, const vector<int> &C, const vector<vector<int>> &S,
              const vector<int> &T) {
  vector<int> last_day(26, 0);
  int score = 0;
  rep(i, 0, D) {
    score += S[i][T[i] - 1];
    last_day[T[i] - 1] = i + 1;
    rep(j, 0, 26) { score -= C[j] * (i + 1 - last_day[j]); }
  }
  return score;
}

vector<int> greedy(int D, const vector<int> &C, const vector<vector<int>> &S) {
  vector<int> last_day(26, 0);
  int score = 0;
  vector<int> res;
  rep(i, 0, D) {
    int max_score = -INF;
    int max_type = -1;
    rep(j, 0, 26) {
      // タイプjのコンテストを開催したときのスコアを計算
      int now_score = score;
      now_score += S[i][j];
      int tmp = last_day[j];
      last_day[j] = i;
      rep(k, 0, 26) { now_score -= C[k] * (i + 1 - last_day[k]); }
      last_day[j] = tmp;
      if (chmax(max_score, now_score)) {
        max_type = j;
      }
    }
    // max_typeのコンテストを選択
    res.push_back(max_type + 1);
    score += S[i][max_type];
    last_day[max_type] = i;
    rep(j, 0, 26) { score -= C[j] * (i + 1 - last_day[j]); }
  }
  return res;
}

int recalcScore(int D, const vector<int> &C, const vector<vector<int>> &S,
                const vector<int> &T, int score, int target_day, int nxt_type) {
  score -= S[target_day - 1][T[target_day - 1] - 1];
  {
    int ld = target_day - 1;
    while (ld >= 1 && T[ld - 1] != T[target_day - 1]) {
      --ld;
    }
    int rd = target_day + 1;
    score -= C[T[target_day - 1] - 1] * (target_day - ld);
    while (rd <= D && T[rd - 1] != T[target_day - 1]) {
      score -= C[T[target_day - 1] - 1] * (target_day - ld);
      ++rd;
    }
  }
  score += S[target_day - 1][nxt_type - 1];
  {
    int ld = target_day - 1;
    while (ld >= 1 && T[ld - 1] != nxt_type) {
      --ld;
    }
    int rd = target_day + 1;
    score += C[nxt_type - 1] * (target_day - ld);
    while (rd <= D && T[rd - 1] != nxt_type) {
      score += C[nxt_type - 1] * (target_day - ld);
      ++rd;
    }
  }
  return score;
}

void localSearch(int D, const vector<int> &C, const vector<vector<int>> &S,
                 vector<int> &T) {
  random_device seed_gen;
  default_random_engine engine(seed_gen());
  uniform_int_distribution<> day_dist(1, D);
  uniform_int_distribution<> type_dist(1, 25);

  int score = calcScore(D, C, S, T);
  rep(i, 0, MAX_ITR) {
    int target_day = day_dist(engine);
    int nxt_type = type_dist(engine);
    if (nxt_type >= T[target_day - 1]) {
      ++nxt_type;
    }
    if (chmax(score, recalcScore(D, C, S, T, score, target_day, nxt_type))) {
      T[target_day - 1] = nxt_type;
    }
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int D;
  cin >> D;
  vector<int> C(26);
  for (auto &c : C) {
    cin >> c;
  }
  vector<vector<int>> S(D, vector<int>(26));
  rep(i, 0, D) rep(j, 0, 26) { cin >> S[i][j]; }
  vector<int> T = greedy(D, C, S);
#ifdef DEBUG
  cout << "greedy solution -> ";
  rep(i, 0, D) { cout << T[i] << " \\n"[i + 1 == D]; }
#endif
  localSearch(D, C, S, T);
  for (auto &t : T) {
    cout << t << endl;
  }
  return 0;
}

Error: -6
double free or corruption (out)


Fixed submission:

#include <iostream>
#include <random>
#include <string>
#include <vector>
#define rep(i, start, end) for (int i = (int)start; i < (int)end; ++i)
#define rrep(i, start, end) for (int i = (int)start - 1; i >= (int)end; --i)
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return 0;
}

const int INF = 1 << 30;
const int MAX_ITR = 100000;

int calcScore(int D, const vector<int> &C, const vector<vector<int>> &S,
              const vector<int> &T) {
  vector<int> last_day(26, 0);
  int score = 0;
  rep(i, 0, D) {
    score += S[i][T[i] - 1];
    last_day[T[i] - 1] = i + 1;
    rep(j, 0, 26) { score -= C[j] * (i + 1 - last_day[j]); }
  }
  return score;
}

vector<int> greedy(int D, const vector<int> &C, const vector<vector<int>> &S) {
  vector<int> last_day(26, 0);
  int score = 0;
  vector<int> res;
  rep(i, 0, D) {
    int max_score = -INF;
    int max_type = -1;
    rep(j, 0, 26) {
      // タイプjのコンテストを開催したときのスコアを計算
      int now_score = score;
      now_score += S[i][j];
      int tmp = last_day[j];
      last_day[j] = i;
      rep(k, 0, 26) { now_score -= C[k] * (i + 1 - last_day[k]); }
      last_day[j] = tmp;
      if (chmax(max_score, now_score)) {
        max_type = j;
      }
    }
    // max_typeのコンテストを選択
    res.push_back(max_type);
    score += S[i][max_type];
    last_day[max_type] = i;
    rep(j, 0, 26) { score -= C[j] * (i + 1 - last_day[j]); }
  }
  return res;
}

int recalcScore(int D, const vector<int> &C, const vector<vector<int>> &S,
                const vector<int> &T, int score, int target_day, int nxt_type) {
  score -= S[target_day - 1][T[target_day - 1] - 1];
  {
    int ld = target_day - 1;
    while (ld >= 1 && T[ld - 1] != T[target_day - 1]) {
      --ld;
    }
    int rd = target_day + 1;
    score -= C[T[target_day - 1] - 1] * (target_day - ld);
    while (rd <= D && T[rd - 1] != T[target_day - 1]) {
      score -= C[T[target_day - 1] - 1] * (target_day - ld);
      ++rd;
    }
  }
  score += S[target_day - 1][nxt_type - 1];
  {
    int ld = target_day - 1;
    while (ld >= 1 && T[ld - 1] != nxt_type) {
      --ld;
    }
    int rd = target_day + 1;
    score += C[nxt_type - 1] * (target_day - ld);
    while (rd <= D && T[rd - 1] != nxt_type) {
      score += C[nxt_type - 1] * (target_day - ld);
      ++rd;
    }
  }
  return score;
}

void localSearch(int D, const vector<int> &C, const vector<vector<int>> &S,
                 vector<int> &T) {
  random_device seed_gen;
  default_random_engine engine(seed_gen());
  uniform_int_distribution<> day_dist(1, 365);
  uniform_int_distribution<> type_dist(1, 25);

  int score = calcScore(D, C, S, T);
  rep(i, 0, MAX_ITR) {
    int target_day = day_dist(engine);
    int nxt_type = type_dist(engine);
    if (nxt_type >= T[target_day - 1]) {
      ++nxt_type;
    }
    if (chmax(score, recalcScore(D, C, S, T, score, target_day, nxt_type))) {
      T[target_day - 1] = nxt_type;
    }
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int D;
  cin >> D;
  vector<int> C(26);
  for (auto &c : C) {
    cin >> c;
  }
  vector<vector<int>> S(D, vector<int>(26));
  rep(i, 0, D) rep(j, 0, 26) { cin >> S[i][j]; }
  vector<int> T = greedy(D, C, S);
  localSearch(D, C, S, T);
  for (auto &t : T) {
    cout << t << endl;
  }
  return 0;
}