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

#include <chrono>
#include <iostream>
#include <list>
#include <random>
#include <vector>

using namespace std;
typedef long long ll;

int DAYS;
const int TYPES = 26;

vector<int> c;
vector<vector<ll>> s;

ll point;
vector<ll> penalty;

chrono::system_clock::time_point startTime, endTime;
mt19937 engine(random_device{}());

void simulate(vector<int> &t) {
  vector<int> last(TYPES, -1);
  point = 0, penalty.assign(TYPES, 0);
  for (int i = 0; i < DAYS; i++) {
    point += s[i][t[i]], last[t[i]] = i;
    for (int j = 0; j < TYPES; j++) {
      penalty[j] += c[j] * (i - last[j]);
    }
  }
}

void update(vector<int> &t, int x, int y) {
  int lastx = -1, lasty = -1;
  penalty[x] = 0, penalty[y] = 0;
  for (int i = 0; i < DAYS; i++) {
    if (t[i] == x)
      lastx = i;
    if (t[i] == y)
      lasty = i;

    penalty[x] += c[x] * (i - lastx), penalty[y] += c[y] * (i - lasty);
  }
}

ll scoring() {
  ll ret = point;
  for (auto &x : penalty)
    ret -= x;
  return ret;
}

ll mod_rnd(ll mod) { return engine() % mod; }

int main() {
  startTime = chrono::system_clock::now();

  cin >> DAYS;
  c.resize(TYPES);
  for (int i = 0; i < TYPES; i++)
    cin >> c[i];
  s.assign(DAYS, vector<ll>(TYPES));
  for (int i = 0; i < DAYS; i++) {
    for (int j = 0; j < TYPES; j++) {
      cin >> s[i][j];
    }
  }

  vector<int> t(DAYS);
  for (int i = 0; i < DAYS; i++)
    t[i] = i % TYPES;

  simulate(t);
  ll currentScore = scoring();

  while (
      chrono::duration_cast<chrono::milliseconds>(endTime - startTime).count() <
      1950) {
    int ope = mod_rnd(15);
    if (ope == 0) {
      int d = -1, q = -1;
      do {
        d = mod_rnd(DAYS), q = mod_rnd(TYPES);
      } while (t[d] == q);

      int old = t[d];
      t[d] = q;
      point -= s[d][old], point += s[d][q];
      update(t, old, q);
      ll changedScore = scoring();

      if (currentScore < changedScore)
        currentScore = changedScore;
      else {
        t[d] = old;
        point += s[d][old], point -= s[d][q];
        update(t, old, q);
      }
    } else {
      int x = -1, y = -1;
      do {
        x = mod_rnd(DAYS), y = mod_rnd(DAYS);
      } while (x == y);

      point -= s[x][t[x]], point -= s[y][t[y]];
      swap(t[x], t[y]);
      point += s[x][t[x]], point += s[y][t[y]];
      update(t, t[x], t[y]);
      ll changedScore = scoring();

      if (currentScore < changedScore)
        currentScore = changedScore;
      else {
        point -= s[x][t[x]], point -= s[y][t[y]];
        swap(t[x], t[y]);
        point += s[x][t[x]], point += s[y][t[y]];
        update(t, t[x], t[y]);
      }
    }
    endTime = chrono::system_clock::now();
  }

  for (auto &x : t)
    cout << x + 1 << endl;
  return 0;
}

Error: -6
double free or corruption (out)


Fixed submission:

#include <chrono>
#include <iostream>
#include <list>
#include <random>
#include <vector>

using namespace std;
typedef long long ll;

int DAYS;
const int TYPES = 26;

vector<int> c;
vector<vector<ll>> s;

ll point;
vector<ll> penalty;

chrono::system_clock::time_point startTime, endTime;
mt19937 engine(random_device{}());

void simulate(vector<int> &t) {
  vector<int> last(TYPES, -1);
  point = 0, penalty.assign(TYPES, 0);
  for (int i = 0; i < DAYS; i++) {
    point += s[i][t[i]], last[t[i]] = i;
    for (int j = 0; j < TYPES; j++) {
      penalty[j] += c[j] * (i - last[j]);
    }
  }
}

void update(vector<int> &t, int x, int y) {
  int lastx = -1, lasty = -1;
  penalty[x] = 0, penalty[y] = 0;
  for (int i = 0; i < DAYS; i++) {
    if (t[i] == x)
      lastx = i;
    if (t[i] == y)
      lasty = i;

    penalty[x] += c[x] * (i - lastx), penalty[y] += c[y] * (i - lasty);
  }
}

ll scoring() {
  ll ret = point;
  for (auto &x : penalty)
    ret -= x;
  return ret;
}

ll mod_rnd(ll mod) { return engine() % mod; }

int main() {
  startTime = chrono::system_clock::now();

  cin >> DAYS;
  c.resize(TYPES);
  for (int i = 0; i < TYPES; i++)
    cin >> c[i];
  s.assign(DAYS, vector<ll>(TYPES));
  for (int i = 0; i < DAYS; i++) {
    for (int j = 0; j < TYPES; j++) {
      cin >> s[i][j];
    }
  }

  vector<int> t(DAYS);
  for (int i = 0; i < DAYS; i++)
    cin >> t[i], t[i]--;

  simulate(t);
  ll currentScore = scoring();

  while (
      chrono::duration_cast<chrono::milliseconds>(endTime - startTime).count() <
      1950) {
    int ope = mod_rnd(10);
    if (ope == 0) {
      int d = -1, q = -1;
      do {
        d = mod_rnd(DAYS), q = mod_rnd(TYPES);
      } while (t[d] == q);

      int old = t[d];
      t[d] = q;
      point -= s[d][old], point += s[d][q];
      update(t, old, q);
      ll changedScore = scoring();

      if (currentScore < changedScore)
        currentScore = changedScore;
      else {
        t[d] = old;
        point += s[d][old], point -= s[d][q];
        update(t, old, q);
      }
    } else {
      int x = -1, y = -1;
      do {
        x = mod_rnd(DAYS), y = mod_rnd(DAYS);
      } while (x == y);

      point -= s[x][t[x]], point -= s[y][t[y]];
      swap(t[x], t[y]);
      point += s[x][t[x]], point += s[y][t[y]];
      ll changedScore = scoring();

      if (currentScore < changedScore)
        currentScore = changedScore;
      else {
        point -= s[x][t[x]], point -= s[y][t[y]];
        swap(t[x], t[y]);
        point += s[x][t[x]], point += s[y][t[y]];
      }
    }
    endTime = chrono::system_clock::now();
  }

  for (auto &x : t)
    cout << x + 1 << endl;
  return 0;
}