Problem p02618 (C++)

Buggy submission (status: Runtime Error):
/*/ Author: kal013 /*/
/*/ Author: kal013 /*/
// #pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
using namespace __gnu_pbds;

template <class T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <class key, class value, class cmp = std::less<key>>
using ordered_map =
    tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;

struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};

template <class T> ostream &operator<<(ostream &os, vector<T> V) {
  os << "[ ";
  for (auto v : V)
    os << v << " ";
  return os << "]";
}
template <class T> ostream &operator<<(ostream &os, set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class T> ostream &operator<<(ostream &os, unordered_set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class T> ostream &operator<<(ostream &os, multiset<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class T> ostream &operator<<(ostream &os, ordered_set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class L, class R> ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class L, class R> ostream &operator<<(ostream &os, map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
template <class L, class R>
ostream &operator<<(ostream &os, unordered_map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
template <class L, class R, class chash = std::hash<R>>
ostream &operator<<(ostream &os, gp_hash_table<L, R, chash> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...) 1
#endif

mt19937_64 random_number_generator(
    chrono::steady_clock::now().time_since_epoch().count());

inline int64_t random_long(long long l, long long r) {
  uniform_int_distribution<int64_t> generator(l, r);
  return generator(random_number_generator);
}
inline int64_t random_long() {
  uniform_int_distribution<int64_t> generator(LLONG_MIN, LLONG_MAX);
  return generator(random_number_generator);
}

/*/---------------------------Defines----------------------/*/
typedef vector<int> vi;
typedef pair<int, int> pii;

#define ll long long
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(v) (v).begin(), (v).end()
/*/-----------------------Modular Arithmetic---------------/*/

const int mod = 1e9 + 7;
inline int add(int x, int y) {
  x += y;
  if (x >= mod)
    return x - mod;
  return x;
}
inline int sub(int x, int y) {
  x -= y;
  if (x < 0)
    return x + mod;
  return x;
}
inline int mul(int x, int y) { return (x * 1ll * y) % mod; }
inline int power(int x, int y) {
  int ans = 1;
  while (y) {
    if (y & 1)
      ans = mul(ans, x);
    x = mul(x, x);
    y >>= 1;
  }
  return ans;
}
inline int inv(int x) { return power(x, mod - 2); }
/*/-----------------------------Code begins----------------------------------/*/

struct contest_scheduling {

  int D;
  int c[26];

  long long satisfaction;
  vector<int> s[26];

  set<int> last_occur[26];

  vector<int> curr_t;

  friend istream &operator>>(istream &is, contest_scheduling &p) {
    is >> p.D;
    for (int i = 0; i < 26; ++i) {
      p.s[i].resize(p.D, 0);
      is >> p.c[i];
    }

    for (int i = 0; i < p.D; ++i) {
      for (int j = 0; j < 26; ++j) {
        is >> p.s[j][i];
      }
    }

    return is;
  }

  void calculate_whole(const vector<int> &t) {
    assert(t.size() == D);

    for (int i = 0; i < 26; ++i) {
      last_occur[i].clear();
      last_occur[i].insert(-1);
    }

    satisfaction = 0;
    curr_t.resize(D);
    for (int i = 0; i < D; ++i) {
      int type = t[i] - 1;
      curr_t[i] = type;
      satisfaction += s[type][i];
      last_occur[type].insert(i);
      for (int j = 0; j < 26; ++j) {
        satisfaction -= c[j] * (i - (*last_occur[j].rbegin()));
      }
      // cout<<satisfaction<<endl;
    }
  }

  inline int get_next_day(int day, int type) {
    auto it = last_occur[type].upper_bound(day);
    if (it == last_occur[type].end())
      return D;
    return (*it);
  }

  inline int get_prev_day(int day, int type) {
    auto it = last_occur[type].lower_bound(day);
    if (it == last_occur[type].begin())
      return -1;
    --it;
    return (*it);
  }

  inline long long difference_values(int day, int type) {
    int next_day = get_next_day(day, type);
    int prev_day = get_prev_day(day, type);

    return c[type] * (day - prev_day) * (next_day - day);
  }

  void improve_day(int day, int type) {
    if (curr_t[day] == type)
      return;

    ll prev_satisfaction = satisfaction;
    satisfaction -= s[curr_t[day]][day];
    satisfaction += s[type][day];

    satisfaction -= difference_values(day, curr_t[day]);
    satisfaction += difference_values(day, type);

    if (satisfaction <= prev_satisfaction) {
      satisfaction = prev_satisfaction;
      return;
    }

    last_occur[curr_t[day]].erase(day);
    last_occur[type].insert(day);

    curr_t[day] = type;
  }
};

void solve() {
  contest_scheduling U;

  auto start = std::chrono::high_resolution_clock::now();

  cin >> U;

  int D = U.D;
  vector<int> t(D);

  for (int i = 0; i < D; ++i) {
    t[i] = random_long(0, 25);
  }

  U.calculate_whole(t);

  auto stop = std::chrono::high_resolution_clock::now();

  auto duration =
      std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

  ll time_limit = (ll)(1.5e9);
  while (duration.count() < time_limit) {

    int d_change = random_long(0, D - 1);
    int type = random_long(0, 25);

    U.improve_day(d_change, type);

    stop = std::chrono::high_resolution_clock::now();
    duration =
        std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
  }

  for (auto e : U.curr_t) {
    cout << e + 1 << "\n";
  }
}
int main() {
  // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with
  // unordered set Or use gp_hash_table<X,null_type>
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout << fixed << setprecision(25);
  cerr << fixed << setprecision(10);
  auto start = std::chrono::high_resolution_clock::now();
  int t = 1;
  // cin>>t;
  while (t--) {
    solve();
  }
  auto stop = std::chrono::high_resolution_clock::now();
  auto duration =
      std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

  // cerr << "Time taken : " << ((long double)duration.count())/((long double)
  // 1e9) <<"s "<< endl;
}


Fixed submission:
/*/ Author: kal013 /*/
/*/ Author: kal013 /*/
// #pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
using namespace std;
using namespace __gnu_pbds;

template <class T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <class key, class value, class cmp = std::less<key>>
using ordered_map =
    tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;

struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};

template <class T> ostream &operator<<(ostream &os, vector<T> V) {
  os << "[ ";
  for (auto v : V)
    os << v << " ";
  return os << "]";
}
template <class T> ostream &operator<<(ostream &os, set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class T> ostream &operator<<(ostream &os, unordered_set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class T> ostream &operator<<(ostream &os, multiset<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class T> ostream &operator<<(ostream &os, ordered_set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class L, class R> ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class L, class R> ostream &operator<<(ostream &os, map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
template <class L, class R>
ostream &operator<<(ostream &os, unordered_map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
template <class L, class R, class chash = std::hash<R>>
ostream &operator<<(ostream &os, gp_hash_table<L, R, chash> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...) 1
#endif

mt19937_64 random_number_generator(
    chrono::steady_clock::now().time_since_epoch().count());

inline int64_t random_long(long long l, long long r) {
  uniform_int_distribution<int64_t> generator(l, r);
  return generator(random_number_generator);
}
inline int64_t random_long() {
  uniform_int_distribution<int64_t> generator(LLONG_MIN, LLONG_MAX);
  return generator(random_number_generator);
}

/*/---------------------------Defines----------------------/*/
typedef vector<int> vi;
typedef pair<int, int> pii;

#define ll long long
#define F first
#define S second
#define pb push_back
#define endl "\n"
#define all(v) (v).begin(), (v).end()
/*/-----------------------Modular Arithmetic---------------/*/

const int mod = 1e9 + 7;
inline int add(int x, int y) {
  x += y;
  if (x >= mod)
    return x - mod;
  return x;
}
inline int sub(int x, int y) {
  x -= y;
  if (x < 0)
    return x + mod;
  return x;
}
inline int mul(int x, int y) { return (x * 1ll * y) % mod; }
inline int power(int x, int y) {
  int ans = 1;
  while (y) {
    if (y & 1)
      ans = mul(ans, x);
    x = mul(x, x);
    y >>= 1;
  }
  return ans;
}
inline int inv(int x) { return power(x, mod - 2); }
/*/-----------------------------Code begins----------------------------------/*/

struct contest_scheduling {

  int D;
  int c[26];

  long long satisfaction;
  vector<int> s[26];

  set<int> last_occur[26];

  vector<int> curr_t;

  friend istream &operator>>(istream &is, contest_scheduling &p) {
    is >> p.D;
    for (int i = 0; i < 26; ++i) {
      p.s[i].resize(p.D, 0);
      is >> p.c[i];
    }

    for (int i = 0; i < p.D; ++i) {
      for (int j = 0; j < 26; ++j) {
        is >> p.s[j][i];
      }
    }

    return is;
  }

  void calculate_whole(const vector<int> &t) {
    assert(t.size() == D);

    for (int i = 0; i < 26; ++i) {
      last_occur[i].clear();
      last_occur[i].insert(-1);
    }

    satisfaction = 0;
    curr_t.resize(D);
    for (int i = 0; i < D; ++i) {
      int type = t[i];
      curr_t[i] = type;
      satisfaction += s[type][i];
      last_occur[type].insert(i);
      for (int j = 0; j < 26; ++j) {
        satisfaction -= c[j] * (i - (*last_occur[j].rbegin()));
      }
      // cout<<satisfaction<<endl;
    }
  }

  inline int get_next_day(int day, int type) {
    auto it = last_occur[type].upper_bound(day);
    if (it == last_occur[type].end())
      return D;
    return (*it);
  }

  inline int get_prev_day(int day, int type) {
    auto it = last_occur[type].lower_bound(day);
    if (it == last_occur[type].begin())
      return -1;
    --it;
    return (*it);
  }

  inline long long difference_values(int day, int type) {
    int next_day = get_next_day(day, type);
    int prev_day = get_prev_day(day, type);

    return c[type] * (day - prev_day) * (next_day - day);
  }

  void improve_day(int day, int type) {
    if (curr_t[day] == type)
      return;

    ll prev_satisfaction = satisfaction;
    satisfaction -= s[curr_t[day]][day];
    satisfaction += s[type][day];

    satisfaction -= difference_values(day, curr_t[day]);
    satisfaction += difference_values(day, type);

    if (satisfaction <= prev_satisfaction) {
      satisfaction = prev_satisfaction;
      return;
    }

    last_occur[curr_t[day]].erase(day);
    last_occur[type].insert(day);

    curr_t[day] = type;
  }
};

void solve() {
  contest_scheduling U;

  auto start = std::chrono::high_resolution_clock::now();

  cin >> U;

  int D = U.D;
  vector<int> t(D);

  for (int i = 0; i < D; ++i) {
    t[i] = random_long(0, 25);
  }

  U.calculate_whole(t);

  auto stop = std::chrono::high_resolution_clock::now();

  auto duration =
      std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

  ll time_limit = (ll)(1.5e9);
  while (duration.count() < time_limit) {

    int d_change = random_long(0, D - 1);
    int type = random_long(0, 25);

    U.improve_day(d_change, type);

    stop = std::chrono::high_resolution_clock::now();
    duration =
        std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
  }

  for (auto e : U.curr_t) {
    cout << e + 1 << "\n";
  }
}
int main() {
  // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with
  // unordered set Or use gp_hash_table<X,null_type>
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout << fixed << setprecision(25);
  cerr << fixed << setprecision(10);
  auto start = std::chrono::high_resolution_clock::now();
  int t = 1;
  // cin>>t;
  while (t--) {
    solve();
  }
  auto stop = std::chrono::high_resolution_clock::now();
  auto duration =
      std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);

  // cerr << "Time taken : " << ((long double)duration.count())/((long double)
  // 1e9) <<"s "<< endl;
}