Problem p02618 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <array>
#include <iostream>
#include <set>
#include <vector>

uint64_t xor64(void) {
  static uint64_t x = 88172645463325252ULL;
  x = x ^ (x << 7);
  return x = x ^ (x >> 9);
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  int D;
  std::cin >> D;
  int c[26];
  for (auto &ci : c)
    std::cin >> ci;
  std::vector<std::array<int, 26>> s(D);
  for (int d = 0; d < D; ++d) {
    for (auto &si : s[d])
      std::cin >> si;
  }
  std::vector<int> t(D);
  for (int i = 0; i < D; ++i)
    t[i] = i % 26;
  std::set<int> last[26];
  for (auto &li : last)
    li.insert(-1); // sentinel
  int ans = 0;
  for (int d = 0; d < D; ++d) {
    int t1 = t[d];
    ans += s[d][t1];
    last[t1].insert(d);
    for (int i = 0; i < 26; ++i) {
      ans -= c[i] * (d - *last[i].rbegin());
    }
  }
  for (auto &li : last)
    li.insert(D); // sentinel

  // additional score when t[d] = i compare to t[d] = -1
  auto sum_up = [](int d) { return d * (d - 1) / 2; };
  auto score = [&](int d, int i) -> int {
    int res = s[d][i];
    auto it = last[i].lower_bound(d);
    int nd = *it;
    int pd = *--it;
    int diff = sum_up(d - pd) + sum_up(nd - d) - sum_up(nd - pd);
    res -= c[i] * diff;
    return res;
  };

  // hill climbing
  int lm = 0;
  int sc[26];
  for (;;) {
    if ((xor64() >> 25) & 1) {
      int dd = -1, ma = 0;
      for (int d = 0; d < D; ++d) {
        int pi = t[d];
        last[pi].erase(d);
        for (int i = 0; i < 26; ++i)
          sc[i] = score(d, i);
        int mi = std::max_element(sc, sc + 26) - sc;
        int cur = sc[mi] - sc[pi];
        if (ma < cur) {
          ma = cur;
          dd = d;
        }
        last[pi].insert(d);
      }
      if (ma == 0)
        ++lm;
      else {
        int pi = t[dd];
        last[pi].erase(dd);
        for (int i = 0; i < 26; ++i)
          sc[i] = score(dd, i);
        int mi = std::max_element(sc, sc + 26) - sc;
        last[mi].insert(dd);
        lm = 0;
      }
    } else {
      // swap
      int d1 = xor64() % D, d2 = xor64() % D;
      while (d1 < d2 - 16 || d2 < d1 - 16 || t[d1] == t[d2]) {
        d1 = xor64() % D;
        d2 = xor64() % D;
      }
      int pi1 = t[d1], pi2 = t[d2];
      last[pi1].erase(d1);
      int diff = score(d1, pi2) - score(d1, pi1);
      last[pi2].insert(d1);
      last[pi2].erase(d2);
      diff += score(d2, pi1) - score(d2, pi2);
      if (diff > 0) {
        last[pi1].insert(d2);
        t[d1] = pi2;
        t[d2] = pi1;
        lm = 0;
      } else {
        last[pi2].insert(d2);
        last[pi2].erase(d1);
        last[pi1].insert(d1);
        ++lm;
      }
    }
    if (lm >= 1000)
      break;
  }
  for (auto ti : t)
    std::cout << ti + 1 << "\n";
  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <iostream>
#include <set>
#include <vector>

uint64_t xor64(void) {
  static uint64_t x = 88172645463325252ULL;
  x = x ^ (x << 7);
  return x = x ^ (x >> 9);
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  int D;
  std::cin >> D;
  int c[26];
  for (auto &ci : c)
    std::cin >> ci;
  std::vector<std::array<int, 26>> s(D);
  for (int d = 0; d < D; ++d) {
    for (auto &si : s[d])
      std::cin >> si;
  }
  std::vector<int> t(D);
  for (int i = 0; i < D; ++i)
    t[i] = i % 26;
  std::set<int> last[26];
  for (auto &li : last)
    li.insert(-1); // sentinel
  int ans = 0;
  for (int d = 0; d < D; ++d) {
    int t1 = t[d];
    ans += s[d][t1];
    last[t1].insert(d);
    for (int i = 0; i < 26; ++i) {
      ans -= c[i] * (d - *last[i].rbegin());
    }
  }
  for (auto &li : last)
    li.insert(D); // sentinel

  // additional score when t[d] = i compare to t[d] = -1
  auto sum_up = [](int d) { return d * (d - 1) / 2; };
  auto score = [&](int d, int i) -> int {
    int res = s[d][i];
    auto it = last[i].lower_bound(d);
    int nd = *it;
    int pd = *--it;
    int diff = sum_up(d - pd) + sum_up(nd - d) - sum_up(nd - pd);
    res -= c[i] * diff;
    return res;
  };

  // hill climbing
  int lm = 0;
  int sc[26];
  for (;;) {
    if ((xor64() >> 25) & 1) {
      int dd = -1, ma = 0;
      for (int d = 0; d < D; ++d) {
        int pi = t[d];
        last[pi].erase(d);
        for (int i = 0; i < 26; ++i)
          sc[i] = score(d, i);
        int mi = std::max_element(sc, sc + 26) - sc;
        int cur = sc[mi] - sc[pi];
        if (ma < cur) {
          ma = cur;
          dd = d;
        }
        last[pi].insert(d);
      }
      if (ma == 0)
        ++lm;
      else {
        int pi = t[dd];
        last[pi].erase(dd);
        for (int i = 0; i < 26; ++i)
          sc[i] = score(dd, i);
        int mi = std::max_element(sc, sc + 26) - sc;
        last[mi].insert(dd);
        lm = 0;
      }
    } else {
      // swap
      int d1 = xor64() % D, d2 = xor64() % D;
      while (d1 < d2 - 16 || d2 < d1 - 16 || t[d1] == t[d2]) {
        d1 = xor64() % D;
        d2 = xor64() % D;
      }
      int pi1 = t[d1], pi2 = t[d2];
      last[pi1].erase(d1);
      int diff = score(d1, pi2) - score(d1, pi1);
      last[pi2].insert(d1);
      last[pi2].erase(d2);
      diff += score(d2, pi1) - score(d2, pi2);
      if (diff > 0) {
        last[pi1].insert(d2);
        t[d1] = pi2;
        t[d2] = pi1;
        lm = 0;
      } else {
        last[pi2].insert(d2);
        last[pi2].erase(d1);
        last[pi1].insert(d1);
        ++lm;
      }
    }
    if (lm >= 10)
      break;
  }
  for (auto ti : t)
    std::cout << ti + 1 << "\n";
  return 0;
}