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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U> using Pa = pair<T, U>;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;

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

class TimeCheck {
private:
  chrono::system_clock::time_point start, end;

public:
  TimeCheck() { start = chrono::system_clock::now(); }

  double nowTime() {
    end = chrono::system_clock::now();
    double ti = static_cast<double>(
        chrono::duration_cast<chrono::microseconds>(end - start).count() /
        1000.0);
    return ti;
  }
};

const int D = 365;
const int M = 26;
vec<int> C(M);
int Csum = 0;
vvec<int> S(D, vec<int>(M));

int getRndDay() { return xor128() % D; }

int getRnd(int n) { return xor128() % n; }

using arr = array<int, M>;

struct state {
  vec<int> res;
  int day;
  arr last;
  int score;
  int weight = 0;
  state() {
    last = {};
    score = 0;
    day = 0;
  }
  void add(int type) {
    day++;
    score += S[(int)res.size()][type];
    res.push_back(type);
    weight += Csum;
    weight -= C[type] * (day - last[type]);
    score -= weight;
    last[type] = day;
    //        for(int i=0;i<M;i++) if(i!=type) score -= C[i]*(day-last[i]);
  }

  bool operator<(const state &R) const { return score > R.score; }

  void print() {
    for (auto &x : res)
      cout << x + 1 << "\\n";
  }
};

const int width = 800;
const int lower = 10000;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  TimeCheck TC;
  int d;
  cin >> d;
  for (auto &x : C) {
    cin >> x;
    Csum += x;
  }
  for (auto &v : S)
    for (auto &x : v)
      cin >> x;
  state init;
  vec<state> states;
  vvec<int> good(D);
  for (int i = 0; i < D; i++) {
    for (int j = 0; j < M; j++)
      if (S[i][j] >= lower)
        good[i].push_back(j);
  }
  states.push_back(init);
  for (int d = 0; d < D; d++) {
    vec<state> neS;
    for (auto &now : states) {
      vec<state> comp;
      for (auto &x : good[d]) {
        state ne = now;
        ne.add(x);
        comp.push_back(ne);
      }
      sort(comp.begin(), comp.end());
      if (comp.size() > 7)
        comp.resize(7);
      for (auto &x : comp)
        neS.push_back(x);
    }
    sort(neS.begin(), neS.end());
    if (neS.size() > width)
      neS.resize(width);
    states.swap(neS);
  }

  auto now = states[0];
  cerr << now.score << "\\n";
  //    now.print();
  //    return 0;
  vec<set<int>> s(M);
  for (int i = 0; i < D; i++)
    s[now.res[i]].insert(i);
  for (int i = 0; i < M; i++) {
    s[i].insert(-1);
    s[i].insert(D);
  }

  auto getsum = [&](int len) {
    assert(len >= 0);
    return len * (len + 1) / 2;
  };

  int loop = 0, update = 0;
  while (TC.nowTime() < 1950) {
    int day = getRndDay();
    int nowScore = now.score;
    int n = good[day].size();
    if (n == 1)
      continue;
    int nowType = now.res[day];
    int bestType = -1;
    int bestScore = nowScore;
    loop++;
    for (int i = 0; i < n; i++) {
      int nextType = good[day][i];
      if (nextType == nowType) {
        continue;
      }
      int nextScore = nowScore + S[day][nextType] - S[day][nowType];
      auto r = s[nowType].upper_bound(day);
      auto l = r;
      l--;
      l--;
      nextScore +=
          (getsum(*r - day - 1) + getsum(day - *l - 1) - getsum(*r - *l - 1)) *
          C[nowType];
      r = s[nextType].upper_bound(day);
      l = r;
      l--;
      nextScore +=
          (-getsum(*r - day - 1) - getsum(day - *l - 1) + getsum(*r - *l - 1)) *
          C[nextType];
      if (nextScore >= bestScore) {
        bestScore = nextScore;
        bestType = nextType;
      }
    }
    if (bestType != -1) {
      update++;
      now.res[day] = bestType;
      now.score = bestScore;
      s[nowType].erase(day);
      s[bestType].insert(day);
    }
  }
  cerr << loop << " " << update << "\\n";
  cerr << now.score << "\\n";
  states[0].print();
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U> using Pa = pair<T, U>;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;

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

class TimeCheck {
private:
  chrono::system_clock::time_point start, end;

public:
  TimeCheck() { start = chrono::system_clock::now(); }

  double nowTime() {
    end = chrono::system_clock::now();
    double ti = static_cast<double>(
        chrono::duration_cast<chrono::microseconds>(end - start).count() /
        1000.0);
    return ti;
  }
};

const int D = 365;
const int M = 26;
vec<int> C(M);
int Csum = 0;
vvec<int> S(D, vec<int>(M));

int getRndDay() { return xor128() % D; }

int getRnd(int n) { return xor128() % n; }

using arr = array<int, M>;

struct state {
  vec<int> res;
  int day;
  arr last;
  int score;
  int weight = 0;
  state() {
    last = {};
    score = 0;
    day = 0;
  }
  void add(int type) {
    day++;
    score += S[(int)res.size()][type];
    res.push_back(type);
    weight += Csum;
    weight -= C[type] * (day - last[type]);
    score -= weight;
    last[type] = day;
    //        for(int i=0;i<M;i++) if(i!=type) score -= C[i]*(day-last[i]);
  }

  bool operator<(const state &R) const { return score > R.score; }

  void print() {
    for (auto &x : res)
      cout << x + 1 << "\\n";
  }
};

const int width = 1000;
const int lower = 10000;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  TimeCheck TC;
  int d;
  cin >> d;
  for (auto &x : C) {
    cin >> x;
    Csum += x;
  }
  for (auto &v : S)
    for (auto &x : v)
      cin >> x;
  state init;
  vec<state> states;
  vvec<int> good(D);
  for (int i = 0; i < D; i++) {
    for (int j = 0; j < M; j++)
      if (S[i][j] >= lower)
        good[i].push_back(j);
  }
  states.push_back(init);
  for (int d = 0; d < D; d++) {
    vec<state> neS;
    for (auto &now : states) {
      vec<state> comp;
      for (auto &x : good[d]) {
        state ne = now;
        ne.add(x);
        comp.push_back(ne);
      }
      sort(comp.begin(), comp.end());
      if (comp.size() > 7)
        comp.resize(7);
      for (auto &x : comp)
        neS.push_back(x);
    }
    sort(neS.begin(), neS.end());
    if (neS.size() > width)
      neS.resize(width);
    states.swap(neS);
  }

  auto now = states[0];
  cerr << now.score << "\\n";
  now.print();
  return 0;
  vec<set<int>> s(M);
  for (int i = 0; i < D; i++)
    s[now.res[i]].insert(i);
  for (int i = 0; i < M; i++) {
    s[i].insert(-1);
    s[i].insert(D);
  }

  auto getsum = [&](int len) {
    assert(len >= 0);
    return len * (len + 1) / 2;
  };

  int loop = 0, update = 0;
  while (TC.nowTime() < 1950) {
    int day = getRndDay();
    int nowScore = now.score;
    int n = good[day].size();
    if (n == 1)
      continue;
    int nowType = now.res[day];
    int nextType = good[day][getRnd(n)];
    if (nowType == nextType)
      continue;
    loop++;
    int nextScore = nowScore + S[day][nextType] - S[day][nowType];
    auto r = s[nowType].upper_bound(day);
    auto l = r;
    l--;
    l--;
    nextScore +=
        (getsum(*r - day - 1) + getsum(day - *l - 1) - getsum(*r - *l - 1)) *
        C[nowType];
    r = s[nextType].upper_bound(day);
    l = r;
    l--;
    nextScore +=
        (-getsum(*r - day - 1) - getsum(day - *l - 1) + getsum(*r - *l - 1)) *
        C[nextType];
    if (nextScore >= nowScore) {
      update++;
      now.res[day] = nextType;
      now.score = nextScore;
      s[nowType].erase(day);
      s[nextType].insert(day);
    }
  }
  cerr << loop << " " << update << "\\n";
  //    cerr << now.score << "\\n";
  states[0].print();
}