Problem p02618 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

int xor64(void) {
  static unsigned long long x = 88172645463325252ULL;
  x ^= x << 13;
  x ^= x >> 7;
  x ^= x << 17;
  return int(x & 0x7fffffff);
}

int D;
vector<int> C;
vector<vector<int>> S;

struct State {
  vector<int> T;
  vector<set<int>> X;
  long long score;
  State() : T(D, -1), X(26, set<int>{-1, D}) {
    score = 0;
    for (int i = 0; i < 26; i++)
      score -= (long long)C[i] * D * (D + 1) / 2;
  }

  void add(int d, int t) {
    // assert(T[d]==-1);
    // assert(X[t].count(d)==0);

    auto p1 = X[t].lower_bound(d);
    auto p0 = p1;
    p0--;
    score += (long long)C[t] * (d - *p0) * (*p1 - d);
    score += S[d][t];
    X[t].insert(d);
    T[d] = t;
  }

  long long add_dry(int d, int t) {
    auto p1 = X[t].lower_bound(d);
    auto p0 = p1;
    p0--;
    return (long long)C[t] * (d - *p0) * (*p1 - d) + S[d][t];
  }

  void remove(int d) {
    // assert(T[d]!=-1);
    // assert(X[T[d]].count(d)>0);

    int t = T[d];
    auto p = X[t].find(d);
    auto p0 = p;
    p0--;
    auto p1 = p;
    p1++;
    score -= (long long)C[t] * (d - *p0) * (*p1 - d);
    score -= S[d][t];
    X[t].erase(d);
    T[d] = -1;
  }
};

int main() {
  //*
  cin >> D;
  C = vector<int>(26);
  for (int &c : C)
    cin >> c;
  S = vector<vector<int>>(D, vector<int>(26));
  for (auto &s : S)
    for (auto &x : s)
      cin >> x;
  /*/
  D = 365;
  C = vector<int>(26);
  for (int &c: C)
      c = xor64()%101;
  S = vector<vector<int>>(D, vector<int>(26));
  for (auto &s: S)
      for (auto &x: s)
          x = xor64()%20001;
  //*/

  /*
  cout<<D<<endl;
  for (int c: C)
      cout<<" "<<c;
  cout<<endl;
  for (auto s: S)
  {
      for (auto x: s)
          cout<<" "<<x;
      cout<<endl;
  }
  */

  long long best = -99999999;
  vector<int> bestT;

  for (int i = 0; i < 1; i++) {

    State state;
    for (int i = 0; i < D; i++)
      state.add(i, xor64() % 26);

    int R = 3500'000;
    // int R = 200'000;
    for (int i = 0; i < R; i++) {
      if (i % 8 == 0) {
        int d = xor64() % D;
        state.remove(d);

        long long m = state.add_dry(d, 0);
        int mt = 0;
        for (int t = 1; t < 26; t++) {
          long long s = state.add_dry(d, t);
          if (s > m) {
            m = s;
            mt = t;
          }
        }
        state.add(d, mt);
      } else {
        int d0 = xor64() % D;
        int d1;
        while (true) {
          // int d = max(1, 20*i/R);
          int d = 7;
          d1 = d0 + xor64() % (2 * d) - d;
          if (0 <= d1 && d1 < D)
            break;
        }
        if (state.T[d0] != state.T[d1]) {
          long long score0 = state.score;
          int t0 = state.T[d0];
          int t1 = state.T[d1];
          state.remove(d0);
          state.remove(d1);
          state.add(d0, t1);
          state.add(d1, t0);
          // if (state.score < score0 && xor64()%(R*8/10)<i)
          if (state.score < score0 - xor64() % max(1, 10000 * (R - i) / R)) {
            state.remove(d0);
            state.remove(d1);
            state.add(d0, t0);
            state.add(d1, t1);
          }
        }
      }
    }

    if (state.score > best) {
      best = state.score;
      bestT = state.T;
    }
  }

  for (int t : bestT)
    cout << t + 1 << endl;
  cerr << best << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

int xor64(void) {
  static unsigned long long x = 88172645463325252ULL;
  x ^= x << 13;
  x ^= x >> 7;
  x ^= x << 17;
  return int(x & 0x7fffffff);
}

int D;
vector<int> C;
vector<vector<int>> S;

struct State {
  vector<int> T;
  vector<set<int>> X;
  long long score;
  State() : T(D, -1), X(26, set<int>{-1, D}) {
    score = 0;
    for (int i = 0; i < 26; i++)
      score -= (long long)C[i] * D * (D + 1) / 2;
  }

  void add(int d, int t) {
    // assert(T[d]==-1);
    // assert(X[t].count(d)==0);

    auto p1 = X[t].lower_bound(d);
    auto p0 = p1;
    p0--;
    score += (long long)C[t] * (d - *p0) * (*p1 - d);
    score += S[d][t];
    X[t].insert(d);
    T[d] = t;
  }

  long long add_dry(int d, int t) {
    auto p1 = X[t].lower_bound(d);
    auto p0 = p1;
    p0--;
    return (long long)C[t] * (d - *p0) * (*p1 - d) + S[d][t];
  }

  void remove(int d) {
    // assert(T[d]!=-1);
    // assert(X[T[d]].count(d)>0);

    int t = T[d];
    auto p = X[t].find(d);
    auto p0 = p;
    p0--;
    auto p1 = p;
    p1++;
    score -= (long long)C[t] * (d - *p0) * (*p1 - d);
    score -= S[d][t];
    X[t].erase(d);
    T[d] = -1;
  }
};

int main() {
  //*
  cin >> D;
  C = vector<int>(26);
  for (int &c : C)
    cin >> c;
  S = vector<vector<int>>(D, vector<int>(26));
  for (auto &s : S)
    for (auto &x : s)
      cin >> x;
  /*/
  D = 365;
  C = vector<int>(26);
  for (int &c: C)
      c = xor64()%101;
  S = vector<vector<int>>(D, vector<int>(26));
  for (auto &s: S)
      for (auto &x: s)
          x = xor64()%20001;
  //*/

  /*
  cout<<D<<endl;
  for (int c: C)
      cout<<" "<<c;
  cout<<endl;
  for (auto s: S)
  {
      for (auto x: s)
          cout<<" "<<x;
      cout<<endl;
  }
  */

  long long best = -99999999;
  vector<int> bestT;

  for (int i = 0; i < 1; i++) {

    State state;
    for (int i = 0; i < D; i++)
      state.add(i, xor64() % 26);

    int R = 4000'000;
    // int R = 200'000;
    for (int i = 0; i < R; i++) {
      if (i % 8 == 0) {
        int d = xor64() % D;
        state.remove(d);

        long long m = state.add_dry(d, 0);
        int mt = 0;
        for (int t = 1; t < 26; t++) {
          long long s = state.add_dry(d, t);
          if (s > m) {
            m = s;
            mt = t;
          }
        }
        state.add(d, mt);
      } else {
        int d0 = xor64() % D;
        int d1;
        while (true) {
          // int d = max(1, 20*i/R);
          int d = 7;
          d1 = d0 + xor64() % (2 * d) - d;
          if (0 <= d1 && d1 < D)
            break;
        }
        if (state.T[d0] != state.T[d1]) {
          long long score0 = state.score;
          int t0 = state.T[d0];
          int t1 = state.T[d1];
          state.remove(d0);
          state.remove(d1);
          state.add(d0, t1);
          state.add(d1, t0);
          // if (state.score < score0 && xor64()%(R*8/10)<i)
          if (state.score < score0 - xor64() % max(1, 10000 * (R - i) / R)) {
            state.remove(d0);
            state.remove(d1);
            state.add(d0, t0);
            state.add(d1, t1);
          }
        }
      }
    }

    if (state.score > best) {
      best = state.score;
      bestT = state.T;
    }
  }

  for (int t : bestT)
    cout << t + 1 << endl;
  cerr << best << endl;
}