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

#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

using namespace std;
using namespace std::chrono;
typedef long long ll;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()

class solver {
public:
  int D;
  vector<ll> c;
  vector<vector<ll>> s;

  void init() {
    cin >> D;
    c.resize(26);
    s.resize(D);
    rep(i, 26) { cin >> c[i]; }
    rep(j, D) {
      s[j].resize(26);
      rep(i, 26) { cin >> s[j][i]; }
    }
  }

  vector<ll> calc(const vector<int> &t) const {
    vector<int> last(26);
    auto down = [&last, this](int d) {
      d++;
      ll v = 0;
      rep(i, 26) { v += c[i] * (d - last[i]); }
      return v;
    };
    int N = t.size();
    vector<ll> v(N);
    rep(i, N) {
      if (i > 0)
        v[i] = v[i - 1];
      v[i] += s[i][t[i]];
      last[t[i]] = i + 1;
      v[i] -= down(i);
    }
    return v;
  }

  vector<int> greedy() const {
    vector<pair<ll, int>> cs;
    rep(i, 26) { cs.emplace_back(c[i], i); }
    sort(all(cs), greater<pair<ll, int>>());

    vector<vector<pair<ll, int>>> ss(D);
    rep(j, D) {
      rep(i, 26) { ss[j].emplace_back(s[j][i], i); }
      sort(all(ss[j]), greater<pair<ll, int>>());
    }

    vector<int> ans;
    ll score = 0;
    for (auto &i : ss) {
      vector<int> ts(ans);
      ts.push_back(i[0].second);
      auto as = calc(ts);
      vector<int> tc(ans);
      tc.push_back(cs[0].second);
      auto ac = calc(tc);
      if (as.back() > ac.back()) {
        ans.push_back(i[0].second);
        score = as.back();
      } else {
        ans.push_back(cs[0].second);
        score = ac.back();
      }
    }

    /*
t[1..D] = 初期解(ランダム生成や、貪欲法で求めたものを利用)
while 時間のある限り:
d と q をランダムに選ぶ。
old = t[d] # 後で戻せるように元の値を記憶しておく
t[d] = q
if 変形前より解が悪化:
    t[d] = old
    */
    system_clock::time_point start = system_clock::now();
    auto t = ans;
    for (;;) {
      system_clock::time_point now = system_clock::now();
      double elapsed = duration_cast<milliseconds>(now - start).count();
      if (elapsed > 1900)
        break;

      auto old = t;
      int d = rand() % D;
      int q = rand() % 26;
      t[d] = q;
      auto tmp = calc(t);

      if (score < tmp.back()) {
        score = tmp.back();
      } else {
        // rollback
        t = old;
      }
    }
    ans = t;
    return ans;
  }

  /*
  fn solve(input: &Input) -> Vec<usize> {
          const TL: f64 = 1.9;
          let mut rng = rand_pcg::Pcg64Mcg::new(890482);
          let mut out = (0..input.D).map(|_| rng.gen_range(0,
  26)).collect::<Vec<_>>(); // random solution let mut score =
  compute_score(&input, &out); while get_time() < TL { if rng.gen_bool(0.5) {
                          let d = rng.gen_range(0, input.D);
                          let q = rng.gen_range(0, 26);
                          let old = out[d];
                          out[d] = q;
                          let new_score = compute_score(&input, &out);
                          if score > new_score {
                                  out[d] = old;
                          } else {
                                  score = new_score;
                          }
                  } else {
                          let d1 = rng.gen_range(0, input.D - 1);
                          let d2 = rng.gen_range(d1 + 1, (d1 +
  16).min(input.D)); out.swap(d1, d2); let new_score = compute_score(&input,
  &out); if score > new_score { out.swap(d1, d2); } else { score = new_score;
                          }
                  }
          }
          out
  }
  */
  vector<int> solve() const {
    auto start = system_clock::now();
    auto get_time = [start]() {
      return duration_cast<milliseconds>(system_clock::now() - start).count();
    };
    const ll TL = 1900;
    vector<int> out(D);
    rep(i, D) {
      out[i] = rand() % 26; // random solution
    }
    auto score = calc(out).back();
    auto cnt = 0;
    while (get_time() < TL) {
      cnt++;
      if (rand() % 2 == 0) {
        const int d = rand() % D;
        const int q = rand() % 26;
        const int old = out[d];
        out[d] = q;
        const ll new_score = calc(out).back();
        if (score > new_score) {
          out[d] = old;
        } else {
          score = new_score;
        }
      } else {
        const int d1 = rand() % (D - 1);
        const int d2 = min(d1 + 1 + (rand() % 16), D - 1);
        swap(out[d1], out[d2]);
        const ll new_score = calc(out).back();
        if (score >= new_score) {
          swap(out[d1], out[d2]);
        } else {
          score = new_score;
          clog << "best: " << score << endl;
        }
      }
    }
    clog << "cnt: " << cnt << endl;
    return out;
  }

  /*
struct State {
  out: Vec<usize>,
  score: i64,
  ds: Vec<Vec<usize>>,
}
  */
  struct State {
    vector<int> out;
    ll score;
    vector<vector<int>> ds;
  };

  /*
fn cost(a: usize, b: usize) -> i64 {
  let d = b - a;
  (d * (d - 1) / 2) as i64
}
  */
  static ll cost(int a, int b) {
    const int d = b - a;
    return ll(d * (d - 1) / 2);
  }

  /*
  impl State {
          fn new(input: &Input, out: Vec<usize>) -> State {
                  let mut ds = vec![vec![]; 26];
                  for d in 0..input.D {
                          ds[out[d]].push(d + 1);
                  }
                  let score = compute_score(&input, &out);
                  State { out, score, ds }
          }
          fn change(&mut self, input: &Input, d: usize, new_i: usize) {
                  let old_i = self.out[d];
                  let p = self.ds[old_i].iter().position(|a| *a == d +
  1).unwrap(); let prev = self.ds[old_i].get(p - 1).cloned().unwrap_or(0); let
  next = self.ds[old_i].get(p + 1).cloned().unwrap_or(input.D + 1);
                  self.ds[old_i].remove(p);
                  self.score += (cost(prev, d + 1) + cost(d + 1, next) -
  cost(prev, next)) * input.c[old_i]; let p = self.ds[new_i].iter().position(|a|
  *a > d + 1).unwrap_or(self.ds[new_i].len()); let prev = self.ds[new_i].get(p -
  1).cloned().unwrap_or(0); let next =
  self.ds[new_i].get(p).cloned().unwrap_or(input.D + 1);
                  self.ds[new_i].insert(p, d + 1);
                  self.score -= (cost(prev, d + 1) + cost(d + 1, next) -
  cost(prev, next)) * input.c[new_i]; self.score += input.s[d][new_i] -
  input.s[d][old_i]; self.out[d] = new_i;
          }
  }
  */
  static State state_new(const solver &input, vector<int> &&out) {
    vector<vector<int>> ds(26, vector<int>());
    rep(d, input.D) { ds[out[d]].push_back(d + 1); }
    ll score = input.calc(out).back();
    return {out, score, ds};
  }
  static void state_change(State &self, const solver &input, int d, int new_i) {
    const auto old_i = self.out[d];
    {
      const auto p =
          find_if(all(self.ds[old_i]), [d](int a) { return a == d + 1; }) -
          self.ds[old_i].begin();
      const auto prev = p - 1 >= 0 ? self.ds[old_i].at(p - 1) : 0;
      const auto next = p + 1 < self.ds[old_i].size() ? self.ds[old_i].at(p + 1)
                                                      : input.D + 1;
      self.ds[old_i].erase(self.ds[old_i].begin() + p);
      self.score += (cost(prev, d + 1) + cost(d + 1, next) - cost(prev, next)) *
                    input.c[old_i];
    }
    const auto new_it =
        find_if(all(self.ds[new_i]), [d](int a) { return a > d + 1; });
    const auto p = new_it != self.ds[new_i].end()
                       ? new_it - self.ds[new_i].begin()
                       : (int)self.ds[new_i].size();
    const auto prev = p - 1 >= 0 ? self.ds[new_i].at(p - 1) : 0;
    const auto next =
        p < self.ds[new_i].size() ? self.ds[new_i].at(p) : input.D + 1;
    self.ds[new_i].insert(self.ds[new_i].begin() + p, d + 1);
    self.score -= (cost(prev, d + 1) + cost(d + 1, next) - cost(prev, next)) *
                  input.c[new_i];
    self.score += input.s[d][new_i] - input.s[d][old_i];
    self.out[d] = new_i;
  }

  /*
fn solve(input: &Input) -> Vec<usize> {
  const T0: f64 = 2e3;
  const T1: f64 = 6e2;
  const TL: f64 = 1.9;
  let mut rng = rand_pcg::Pcg64Mcg::new(890482);
  let mut state = State::new(input, (0..input.D).map(|_| rng.gen_range(0,
26)).collect()); let mut cnt = 0; let mut T = T0; let mut best = state.score;

  let mut best_out = state.out.clone();
  loop {
          cnt += 1;
          if cnt % 100 == 0 {
                  let t = get_time() / TL;
                  if t >= 1.0 {
                          break;
                  }
                  T = T0.powf(1.0 - t) * T1.powf(t);
          }
          let old_score = state.score;
          if rng.gen_bool(0.5) {
                  let d = rng.gen_range(0, input.D);
                  let old = state.out[d];
                  state.change(input, d, rng.gen_range(0, 26));
                  if old_score > state.score &&
!rng.gen_bool(f64::exp((state.score - old_score) as f64 / T)) {
                          state.change(input, d, old);
                  }
          } else {
                  let d1 = rng.gen_range(0, input.D - 1);
                  let d2 = rng.gen_range(d1 + 1, (d1 + 16).min(input.D));
                  let (a, b) = (state.out[d1], state.out[d2]);
                  state.change(input, d1, b);
                  state.change(input, d2, a);
                  if old_score > state.score &&
!rng.gen_bool(f64::exp((state.score - old_score) as f64 / T)) {
                          state.change(input, d1, a);
                          state.change(input, d2, b);
                  }
          }
          if best.setmax(state.score) {
                  best_out = state.out.clone();
          }
  }
  best_out
}
*/
  // SimulatedAnnealing
  vector<int> solve_sa() const {
    auto start = system_clock::now();
    auto get_time = [start]() {
      return duration_cast<milliseconds>(system_clock::now() - start).count();
    };
    vector<double> rlog(0x10000);
    rep(i, 0x10000) { rlog[i] = log((double)rand() / RAND_MAX); }
    const double T0 = 2e3;
    const double T1 = 6e2;
    const ll TL = 1900;
    vector<int> out(D);
    rep(i, D) {
      out[i] = rand() % 26; // random solution
    }
    auto state = state_new(*this, std::move(out));
    auto cnt = 0;
    auto T = T0;
    auto best = state.score;

    auto best_out = state.out;
    for (;;) {
      const auto t = get_time() * 1.0 / TL;
      if (t >= 1.0) {
        break;
      }
      cnt++;
      if (cnt % 100 == 0) {
        T = pow(T0, 1.0 - t) * pow(T1, t);
      }
      const auto old_score = state.score;
      if (rand() % 2 == 0) {
        const int d = rand() % D;
        const int q = rand() % 26;
        const int old = out[d];
        state_change(state, *this, d, q);
        // if (old_score > state.score) {
        //	//clog << fixed << exp((double)(state.score - old_score) / T) <<
        //endl;
        //	//if diff as f64 > T * rlog[cnt & 0xffff] {
        //	auto diff = (double)(state.score - old_score);
        //	auto temp2 = T * rlog[cnt & 0xffff];
        //	clog << fixed << diff << temp2 << endl;
        // }
        // if (old_score > state.score && rand() > RAND_MAX *
        // exp((double)(state.score - old_score) / T)) {
        if (old_score > state.score &&
            (double)(state.score - old_score) > T * rlog[cnt & 0xffff]) {
          state_change(state, *this, d, old);
        }
      } else {
        const int d1 = rand() % (D - 1);
        const int d2 = min(d1 + 1 + (rand() % 16), D - 1);
        const int a = state.out[d1];
        const int b = state.out[d2];
        state_change(state, *this, d1, b);
        state_change(state, *this, d2, a);
        // if (old_score > state.score) {
        //	clog << fixed << exp((double)(state.score - old_score) / T) <<
        //endl;
        // }
        // if (old_score > state.score && rand() > RAND_MAX *
        // exp((double)(state.score - old_score) / T)) {
        if (old_score > state.score &&
            (double)(state.score - old_score) > T * rlog[cnt & 0xffff]) {
          state_change(state, *this, d1, a);
          state_change(state, *this, d2, b);
        }
      }
      if (best < state.score) {
        best = state.score;
        best_out = state.out;
        // clog << "best: " << best << endl;
      }
    }
    // clog << "best: " << best << endl;
    // clog << "cnt: " <<cnt << endl;
    return best_out;
  }
};

int main() {
  solver solver;
  solver.init();
  auto ans = solver.solve_sa();
  for (auto t : ans) {
    cout << (t + 1) << endl;
  }
  return 0;
}


Error: -6
terminate called after throwing an instance of 'std::length_error'
  what():  cannot create std::vector larger than max_size()


Fixed submission:

#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

using namespace std;
using namespace std::chrono;
typedef long long ll;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()

class solver {
public:
  int D;
  vector<ll> c;
  vector<vector<ll>> s;

  void init() {
    cin >> D;
    c.resize(26);
    s.resize(D);
    rep(i, 26) { cin >> c[i]; }
    rep(j, D) {
      s[j].resize(26);
      rep(i, 26) { cin >> s[j][i]; }
    }
  }

  vector<ll> calc(const vector<int> &t) const {
    vector<int> last(26);
    auto down = [&last, this](int d) {
      d++;
      ll v = 0;
      rep(i, 26) { v += c[i] * (d - last[i]); }
      return v;
    };
    int N = t.size();
    vector<ll> v(N);
    rep(i, N) {
      if (i > 0)
        v[i] = v[i - 1];
      v[i] += s[i][t[i]];
      last[t[i]] = i + 1;
      v[i] -= down(i);
    }
    return v;
  }

  vector<int> greedy() const {
    vector<pair<ll, int>> cs;
    rep(i, 26) { cs.emplace_back(c[i], i); }
    sort(all(cs), greater<pair<ll, int>>());

    vector<vector<pair<ll, int>>> ss(D);
    rep(j, D) {
      rep(i, 26) { ss[j].emplace_back(s[j][i], i); }
      sort(all(ss[j]), greater<pair<ll, int>>());
    }

    vector<int> ans;
    ll score = 0;
    for (auto &i : ss) {
      vector<int> ts(ans);
      ts.push_back(i[0].second);
      auto as = calc(ts);
      vector<int> tc(ans);
      tc.push_back(cs[0].second);
      auto ac = calc(tc);
      if (as.back() > ac.back()) {
        ans.push_back(i[0].second);
        score = as.back();
      } else {
        ans.push_back(cs[0].second);
        score = ac.back();
      }
    }

    /*
t[1..D] = 初期解(ランダム生成や、貪欲法で求めたものを利用)
while 時間のある限り:
d と q をランダムに選ぶ。
old = t[d] # 後で戻せるように元の値を記憶しておく
t[d] = q
if 変形前より解が悪化:
    t[d] = old
    */
    system_clock::time_point start = system_clock::now();
    auto t = ans;
    for (;;) {
      system_clock::time_point now = system_clock::now();
      double elapsed = duration_cast<milliseconds>(now - start).count();
      if (elapsed > 1900)
        break;

      auto old = t;
      int d = rand() % D;
      int q = rand() % 26;
      t[d] = q;
      auto tmp = calc(t);

      if (score < tmp.back()) {
        score = tmp.back();
      } else {
        // rollback
        t = old;
      }
    }
    ans = t;
    return ans;
  }

  /*
  fn solve(input: &Input) -> Vec<usize> {
          const TL: f64 = 1.9;
          let mut rng = rand_pcg::Pcg64Mcg::new(890482);
          let mut out = (0..input.D).map(|_| rng.gen_range(0,
  26)).collect::<Vec<_>>(); // random solution let mut score =
  compute_score(&input, &out); while get_time() < TL { if rng.gen_bool(0.5) {
                          let d = rng.gen_range(0, input.D);
                          let q = rng.gen_range(0, 26);
                          let old = out[d];
                          out[d] = q;
                          let new_score = compute_score(&input, &out);
                          if score > new_score {
                                  out[d] = old;
                          } else {
                                  score = new_score;
                          }
                  } else {
                          let d1 = rng.gen_range(0, input.D - 1);
                          let d2 = rng.gen_range(d1 + 1, (d1 +
  16).min(input.D)); out.swap(d1, d2); let new_score = compute_score(&input,
  &out); if score > new_score { out.swap(d1, d2); } else { score = new_score;
                          }
                  }
          }
          out
  }
  */
  vector<int> solve() const {
    auto start = system_clock::now();
    auto get_time = [start]() {
      return duration_cast<milliseconds>(system_clock::now() - start).count();
    };
    const ll TL = 1900;
    vector<int> out(D);
    rep(i, D) {
      out[i] = rand() % 26; // random solution
    }
    auto score = calc(out).back();
    auto cnt = 0;
    while (get_time() < TL) {
      cnt++;
      if (rand() % 2 == 0) {
        const int d = rand() % D;
        const int q = rand() % 26;
        const int old = out[d];
        out[d] = q;
        const ll new_score = calc(out).back();
        if (score > new_score) {
          out[d] = old;
        } else {
          score = new_score;
        }
      } else {
        const int d1 = rand() % (D - 1);
        const int d2 = min(d1 + 1 + (rand() % 16), D - 1);
        swap(out[d1], out[d2]);
        const ll new_score = calc(out).back();
        if (score >= new_score) {
          swap(out[d1], out[d2]);
        } else {
          score = new_score;
          clog << "best: " << score << endl;
        }
      }
    }
    clog << "cnt: " << cnt << endl;
    return out;
  }

  /*
struct State {
  out: Vec<usize>,
  score: i64,
  ds: Vec<Vec<usize>>,
}
  */
  struct State {
    vector<int> out;
    ll score;
    vector<vector<int>> ds;
  };

  /*
fn cost(a: usize, b: usize) -> i64 {
  let d = b - a;
  (d * (d - 1) / 2) as i64
}
  */
  static ll cost(int a, int b) {
    const int d = b - a;
    return ll(d * (d - 1) / 2);
  }

  /*
  impl State {
          fn new(input: &Input, out: Vec<usize>) -> State {
                  let mut ds = vec![vec![]; 26];
                  for d in 0..input.D {
                          ds[out[d]].push(d + 1);
                  }
                  let score = compute_score(&input, &out);
                  State { out, score, ds }
          }
          fn change(&mut self, input: &Input, d: usize, new_i: usize) {
                  let old_i = self.out[d];
                  let p = self.ds[old_i].iter().position(|a| *a == d +
  1).unwrap(); let prev = self.ds[old_i].get(p - 1).cloned().unwrap_or(0); let
  next = self.ds[old_i].get(p + 1).cloned().unwrap_or(input.D + 1);
                  self.ds[old_i].remove(p);
                  self.score += (cost(prev, d + 1) + cost(d + 1, next) -
  cost(prev, next)) * input.c[old_i]; let p = self.ds[new_i].iter().position(|a|
  *a > d + 1).unwrap_or(self.ds[new_i].len()); let prev = self.ds[new_i].get(p -
  1).cloned().unwrap_or(0); let next =
  self.ds[new_i].get(p).cloned().unwrap_or(input.D + 1);
                  self.ds[new_i].insert(p, d + 1);
                  self.score -= (cost(prev, d + 1) + cost(d + 1, next) -
  cost(prev, next)) * input.c[new_i]; self.score += input.s[d][new_i] -
  input.s[d][old_i]; self.out[d] = new_i;
          }
  }
  */
  static State state_new(const solver &input, vector<int> &&out) {
    vector<vector<int>> ds(26, vector<int>());
    rep(d, input.D) { ds[out[d]].push_back(d + 1); }
    ll score = input.calc(out).back();
    return {out, score, ds};
  }
  static void state_change(State &self, const solver &input, int d, int new_i) {
    const auto old_i = self.out[d];
    {
      const auto p =
          find_if(all(self.ds[old_i]), [d](int a) { return a == d + 1; }) -
          self.ds[old_i].begin();
      const auto prev = p - 1 >= 0 ? self.ds[old_i].at(p - 1) : 0;
      const auto next = p + 1 < self.ds[old_i].size() ? self.ds[old_i].at(p + 1)
                                                      : input.D + 1;
      self.ds[old_i].erase(self.ds[old_i].begin() + p);
      self.score += (cost(prev, d + 1) + cost(d + 1, next) - cost(prev, next)) *
                    input.c[old_i];
    }
    const auto new_it =
        find_if(all(self.ds[new_i]), [d](int a) { return a > d + 1; });
    const auto p = new_it != self.ds[new_i].end()
                       ? new_it - self.ds[new_i].begin()
                       : (int)self.ds[new_i].size();
    const auto prev = p - 1 >= 0 ? self.ds[new_i].at(p - 1) : 0;
    const auto next =
        p < self.ds[new_i].size() ? self.ds[new_i].at(p) : input.D + 1;
    self.ds[new_i].insert(self.ds[new_i].begin() + p, d + 1);
    self.score -= (cost(prev, d + 1) + cost(d + 1, next) - cost(prev, next)) *
                  input.c[new_i];
    self.score += input.s[d][new_i] - input.s[d][old_i];
    self.out[d] = new_i;
  }

  /*
fn solve(input: &Input) -> Vec<usize> {
  const T0: f64 = 2e3;
  const T1: f64 = 6e2;
  const TL: f64 = 1.9;
  let mut rng = rand_pcg::Pcg64Mcg::new(890482);
  let mut state = State::new(input, (0..input.D).map(|_| rng.gen_range(0,
26)).collect()); let mut cnt = 0; let mut T = T0; let mut best = state.score;

  let mut best_out = state.out.clone();
  loop {
          cnt += 1;
          if cnt % 100 == 0 {
                  let t = get_time() / TL;
                  if t >= 1.0 {
                          break;
                  }
                  T = T0.powf(1.0 - t) * T1.powf(t);
          }
          let old_score = state.score;
          if rng.gen_bool(0.5) {
                  let d = rng.gen_range(0, input.D);
                  let old = state.out[d];
                  state.change(input, d, rng.gen_range(0, 26));
                  if old_score > state.score &&
!rng.gen_bool(f64::exp((state.score - old_score) as f64 / T)) {
                          state.change(input, d, old);
                  }
          } else {
                  let d1 = rng.gen_range(0, input.D - 1);
                  let d2 = rng.gen_range(d1 + 1, (d1 + 16).min(input.D));
                  let (a, b) = (state.out[d1], state.out[d2]);
                  state.change(input, d1, b);
                  state.change(input, d2, a);
                  if old_score > state.score &&
!rng.gen_bool(f64::exp((state.score - old_score) as f64 / T)) {
                          state.change(input, d1, a);
                          state.change(input, d2, b);
                  }
          }
          if best.setmax(state.score) {
                  best_out = state.out.clone();
          }
  }
  best_out
}
*/
  // SimulatedAnnealing
  vector<int> solve_sa() const {
    auto start = system_clock::now();
    auto get_time = [start]() {
      return duration_cast<milliseconds>(system_clock::now() - start).count();
    };
    vector<double> rlog(RAND_MAX + 1);
    rep(i, RAND_MAX + 1) { rlog[i] = log((double)rand() / RAND_MAX); }
    const double T0 = 2e3;
    const double T1 = 6e2;
    const ll TL = 1900;
    vector<int> out(D);
    rep(i, D) {
      out[i] = rand() % 26; // random solution
    }
    auto state = state_new(*this, std::move(out));
    auto cnt = 0;
    auto T = T0;
    auto best = state.score;

    auto best_out = state.out;
    for (;;) {
      const auto t = get_time() * 1.0 / TL;
      if (t >= 1.0) {
        break;
      }
      cnt++;
      if (cnt % 100 == 0) {
        T = pow(T0, 1.0 - t) * pow(T1, t);
      }
      const auto old_score = state.score;
      if (rand() % 2 == 0) {
        const int d = rand() % D;
        const int q = rand() % 26;
        const int old = out[d];
        state_change(state, *this, d, q);
        // if (old_score > state.score) {
        //	//clog << fixed << exp((double)(state.score - old_score) / T) <<
        //endl;
        //	//if diff as f64 > T * rlog[cnt & 0xffff] {
        //	auto diff = (double)(state.score - old_score);
        //	auto temp2 = T * rlog[cnt & 0xffff];
        //	clog << fixed << diff << temp2 << endl;
        // }
        // if (old_score > state.score && rand() > RAND_MAX *
        // exp((double)(state.score - old_score) / T)) {
        if (old_score > state.score &&
            (double)(state.score - old_score) > T * rlog[cnt & RAND_MAX]) {
          state_change(state, *this, d, old);
        }
      } else {
        const int d1 = rand() % (D - 1);
        const int d2 = min(d1 + 1 + (rand() % 16), D - 1);
        const int a = state.out[d1];
        const int b = state.out[d2];
        state_change(state, *this, d1, b);
        state_change(state, *this, d2, a);
        // if (old_score > state.score) {
        //	clog << fixed << exp((double)(state.score - old_score) / T) <<
        //endl;
        // }
        // if (old_score > state.score && rand() > RAND_MAX *
        // exp((double)(state.score - old_score) / T)) {
        if (old_score > state.score &&
            (double)(state.score - old_score) > T * rlog[cnt & RAND_MAX]) {
          state_change(state, *this, d1, a);
          state_change(state, *this, d2, b);
        }
      }
      if (best < state.score) {
        best = state.score;
        best_out = state.out;
        // clog << "best: " << best << endl;
      }
    }
    // clog << "best: " << best << endl;
    // clog << "cnt: " <<cnt << endl;
    return best_out;
  }
};

int main() {
  solver solver;
  solver.init();
  auto ans = solver.solve_sa();
  for (auto t : ans) {
    cout << (t + 1) << endl;
  }
  return 0;
}