Problem p02618 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <chrono>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string.h>
#include <string>
#include <time.h>
#include <tuple>
#include <vector>
#ifdef _MSC_VER
#include <intrin.h>
#define __builtin_popcount __popcnt
#endif
#define FOR(i, a, b) for (ll i = a; i < b; i++)
#define REP(i, a, b) for (ll i = a; i > b; i--)
#define CST(x) cout << fixed << setprecision(x) // 小数点以下の桁数指定
#define ct(a) cout << a << endl
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repl(i, l, r) for (int i = (1); i < (r); i++)
#define per(i, n) for (int i = ((n)-1); i >= 0; i--)
static const double pi = 3.141592653589793;
using namespace std;
typedef long long ll;
const ll MOD = 998244353;
const ll INF = 1e9 + 7;
const ll mod = 1e9 + 7;

using namespace std::chrono;
inline ll get_time_millisec(void) {
  return static_cast<ll>(
      duration_cast<milliseconds>(steady_clock::now().time_since_epoch())
          .count());
}

unsigned long xor128() {
  static unsigned long x = 123456789, y = 362436069, z = 521288629,
                       w = 88675123;
  unsigned long t = (x ^ (x << 11));
  x = y;
  y = z;
  z = w;
  return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

inline int getRange(int l, int r) { return xor128() % (r + 1 - l) + l; }

class Solver {

private:
  // 要素
  ll D;
  ll C[26];
  ll S[365][26];
  ll date[365];
  pair<int, int> maxC;

public:
  void input() {
    cin >> D;
    // D = 365;

    FOR(i, 0, 26) {
      cin >> C[i];
      if (C[i] > maxC.first) {
        maxC.first = C[i];
        maxC.second = i;
      }
    }

    /*
    FOR(i, 0, 26) {
            C[i] = getRange(0, 100);
            if (C[i] > maxC.first) {
                    maxC.first = C[i];
                    maxC.second = i;
            }
    }
    */

    FOR(i, 0, D) {
      FOR(j, 0, 26) {
        cin >> S[i][j];
        // S[i][j] = getRange(0, 20000);
      }
      date[i] = xor128() % 26;
    }
  }

  int calcScore() {
    ll score = 0;
    ll last[365];
    FOR(i, 0, 26) last[i] = -1;

    FOR(i, 0, D) {
      score += S[i][date[i]];
      last[date[i]] = i;

      FOR(j, 0, 26) {
        ll hiku = C[j] * (i - last[j]);

        score -= hiku;
      }
    }

    return score;
  }

  void init() {}
  void rndchange() {
    ll t = xor128() % D;
    date[t] = xor128() % 26;
  }
  void rndchange2() {
    ll t = xor128() % D;
    if (t == 0)
      swap(date[0], date[1]);
    else if (t == 25)
      swap(date[25], date[24]);
    else {
      int judge = xor128() % 2;
      if (judge == 0)
        swap(date[t], date[t + 1]);
      else
        swap(date[t], date[t - 1]);
    }
  }

  void output() {
    FOR(i, 0, D) { cout << date[i] + 1 << endl; }
    // cout << calcScore() << endl;
  }
};
ll cnt = 0;

Solver solve(void) {

  Solver currentSeq;

  currentSeq.input();
  currentSeq.init();

  Solver bestSeq = currentSeq;
  int bestScore = currentSeq.calcScore();
  int currentScore = bestScore;

  const ll saTimeStart = get_time_millisec();

  const ll saTimeEnd = saTimeStart + 1975; // milli
  double saTimeCurrent = saTimeStart;

  while (saTimeCurrent < saTimeEnd) {

    cnt++;

    Solver nextSeq = currentSeq;

    if (saTimeCurrent < saTimeEnd - 500)
      nextSeq.rndchange();
    else
      nextSeq.rndchange2();

    const int nextScore = nextSeq.calcScore();

    const ll T = saTimeEnd - saTimeStart;
    const ll t = saTimeCurrent - saTimeStart;
    const ll R = 10000;

    // const bool FORCE_NEXT = R * (T - t) > T*((xor128()) % (R));
    // const bool FORCE_NEXT = false;

    double startTemp = 4;
    double endTemp = 1;
    double temp = startTemp + (endTemp - startTemp) * t / T;
    double probability = exp((nextScore - currentScore) / temp);
    const bool FORCE_NEXT = probability > (double)(xor128() % R) / (double)R;

    // const bool FORCE_NEXT = (xor128() % R) > 999;

    if (nextScore > currentScore || FORCE_NEXT) {
      currentScore = nextScore;
      currentSeq = nextSeq;
    }

    if (currentScore > bestScore) {

      bestScore = currentScore;

      // cout << bestScore << endl;
      bestSeq = currentSeq;
    }
    saTimeCurrent = get_time_millisec();
  }

  return bestSeq;
}

int main() {
  cin.tie(0);
  cout.tie(0);
  ios::sync_with_stdio(false);

  Solver ans = solve();
  ans.output();
  // cout << cnt << endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <chrono>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string.h>
#include <string>
#include <time.h>
#include <tuple>
#include <vector>
#ifdef _MSC_VER
#include <intrin.h>
#define __builtin_popcount __popcnt
#endif
#define FOR(i, a, b) for (ll i = a; i < b; i++)
#define REP(i, a, b) for (ll i = a; i > b; i--)
#define CST(x) cout << fixed << setprecision(x) // 小数点以下の桁数指定
#define ct(a) cout << a << endl
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repl(i, l, r) for (int i = (1); i < (r); i++)
#define per(i, n) for (int i = ((n)-1); i >= 0; i--)
static const double pi = 3.141592653589793;
using namespace std;
typedef long long ll;
const ll MOD = 998244353;
const ll INF = 1e9 + 7;
const ll mod = 1e9 + 7;

using namespace std::chrono;
inline ll get_time_millisec(void) {
  return static_cast<ll>(
      duration_cast<milliseconds>(steady_clock::now().time_since_epoch())
          .count());
}

unsigned long xor128() {
  static unsigned long x = 123456789, y = 362436069, z = 521288629,
                       w = 88675123;
  unsigned long t = (x ^ (x << 11));
  x = y;
  y = z;
  z = w;
  return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

inline int getRange(int l, int r) { return xor128() % (r + 1 - l) + l; }

class Solver {

private:
  // 要素
  ll D;
  ll C[26];
  ll S[365][26];
  ll date[365];
  pair<int, int> maxC;

public:
  void input() {
    cin >> D;
    // D = 365;

    FOR(i, 0, 26) {
      cin >> C[i];
      if (C[i] > maxC.first) {
        maxC.first = C[i];
        maxC.second = i;
      }
    }

    /*
    FOR(i, 0, 26) {
            C[i] = getRange(0, 100);
            if (C[i] > maxC.first) {
                    maxC.first = C[i];
                    maxC.second = i;
            }
    }
    */

    FOR(i, 0, D) {
      FOR(j, 0, 26) {
        cin >> S[i][j];
        // S[i][j] = getRange(0, 20000);
      }
      date[i] = xor128() % 26;
    }
  }

  int calcScore() {
    ll score = 0;
    ll last[365];
    FOR(i, 0, 26) last[i] = -1;

    FOR(i, 0, D) {
      score += S[i][date[i]];
      last[date[i]] = i;

      FOR(j, 0, 26) {
        ll hiku = C[j] * (i - last[j]);

        score -= hiku;
      }
    }

    return score;
  }

  void init() {}
  void rndchange() {
    ll t = xor128() % D;
    date[t] = xor128() % 26;
  }
  void rndchange2() {
    ll t = xor128() % (D - 1);
    swap(date[t], date[t + 1]);
  }

  void output() {
    FOR(i, 0, D) { cout << date[i] + 1 << endl; }
    // cout << calcScore() << endl;
  }
};
ll cnt = 0;

Solver solve(void) {

  Solver currentSeq;

  currentSeq.input();
  currentSeq.init();

  Solver bestSeq = currentSeq;
  int bestScore = currentSeq.calcScore();
  int currentScore = bestScore;

  const ll saTimeStart = get_time_millisec();

  const ll saTimeEnd = saTimeStart + 1975; // milli
  double saTimeCurrent = saTimeStart;

  while (saTimeCurrent < saTimeEnd) {

    cnt++;

    Solver nextSeq = currentSeq;

    if (saTimeCurrent < saTimeEnd - 500)
      nextSeq.rndchange();
    else
      nextSeq.rndchange2();

    const int nextScore = nextSeq.calcScore();

    const ll T = saTimeEnd - saTimeStart;
    const ll t = saTimeCurrent - saTimeStart;
    const ll R = 10000;

    // const bool FORCE_NEXT = R * (T - t) > T*((xor128()) % (R));
    // const bool FORCE_NEXT = false;

    double startTemp = 4;
    double endTemp = 1;
    double temp = startTemp + (endTemp - startTemp) * t / T;
    double probability = exp((nextScore - currentScore) / temp);
    const bool FORCE_NEXT = probability > (double)(xor128() % R) / (double)R;

    // const bool FORCE_NEXT = (xor128() % R) > 999;

    if (nextScore > currentScore || FORCE_NEXT) {
      currentScore = nextScore;
      currentSeq = nextSeq;
    }

    if (currentScore > bestScore) {

      bestScore = currentScore;

      // cout << bestScore << endl;
      bestSeq = currentSeq;
    }
    saTimeCurrent = get_time_millisec();
  }

  return bestSeq;
}

int main() {
  cin.tie(0);
  cout.tie(0);
  ios::sync_with_stdio(false);

  Solver ans = solve();
  ans.output();
  // cout << cnt << endl;

  return 0;
}