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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <set>
#include <stdlib.h>
using namespace std;

int d, c[29], s[409][29], p[409], cp[29], rs;
set<int> st[29];

int cc() {
  for (int i = 0; i < 26; i++)
    cp[i] = 0;
  int ans = 0;
  for (int i = 1; i <= d; i++) {
    for (int j = 0; j < 26; j++) {
      if (p[i] == j) {
        cp[j] = i;
        ans += s[i][j];
      } else
        ans -= (i - cp[j]) * c[j];
    }
  }
  return ans;
}

void rm(int n, int k) {
  auto pi = st[k].find(n);
  auto l = pi;
  l--;
  auto r = pi;
  r++;
  int pl = (n - (*l) - 1), pr = ((*r) - n - 1), plr = ((*r) - (*l) - 1);
  st[k].erase(n);
  rs -= s[n][k];
  rs += pl * (pl + 1) / 2 * c[k];
  rs += pr * (pr + 1) / 2 * c[k];
  rs -= plr * (plr + 1) / 2 * c[k];
}

void ins(int n, int k) {
  auto r = st[k].lower_bound(n);
  auto l = r;
  l--;
  int pl = (n - (*l) - 1), pr = ((*r) - n - 1), plr = ((*r) - (*l) - 1);
  st[k].insert(n);
  rs += s[n][k];
  rs -= pl * (pl + 1) / 2 * c[k];
  rs -= pr * (pr + 1) / 2 * c[k];
  rs += plr * (plr + 1) / 2 * c[k];
}

void up(int n, int k) {
  rm(n, p[n]);
  p[n] = k;
  ins(n, p[n]);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> d;
  for (int i = 0; i < 26; i++) {
    cin >> c[i];
    st[i].insert(0);
    st[i].insert(d + 1);
  }
  for (int i = 1; i <= d; i++) {
    for (int j = 0; j < 26; j++)
      cin >> s[i][j];
    p[i] = rand() % 26;
    st[p[i]].insert(i);
  }
  rs = cc();
  double k = 300, sc = 270, kt = 0.99915;
  for (int i = 0; i < 4000000; i++) {
    double e1 = rs;
    int n = (rand() % d) + 1, kp = (rand() % 25) + 1;
    int hk = p[n], tk = (hk + kp) % 26;
    up(n, tk);
    int e2 = rs;
    double pb = exp((e2 - e1) / (k * sc));
    if (pb < rand() / (double)RAND_MAX)
      up(n, hk);
    k *= kt;
  }
  for (int i = 1; i <= d; i++)
    cout << p[i] + 1 << '\\n';
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <set>
#include <stdlib.h>
using namespace std;

int d, c[29], s[409][29], p[409], cp[29], rs;
set<int> st[29];

int cc() {
  for (int i = 0; i < 26; i++)
    cp[i] = 0;
  int ans = 0;
  for (int i = 1; i <= d; i++) {
    for (int j = 0; j < 26; j++) {
      if (p[i] == j) {
        cp[j] = i;
        ans += s[i][j];
      } else
        ans -= (i - cp[j]) * c[j];
    }
  }
  return ans;
}

void rm(int n, int k) {
  auto pi = st[k].find(n);
  auto l = pi;
  l--;
  auto r = pi;
  r++;
  int pl = (n - (*l) - 1), pr = ((*r) - n - 1), plr = ((*r) - (*l) - 1);
  st[k].erase(n);
  rs -= s[n][k];
  rs += pl * (pl + 1) / 2 * c[k];
  rs += pr * (pr + 1) / 2 * c[k];
  rs -= plr * (plr + 1) / 2 * c[k];
}

void ins(int n, int k) {
  auto r = st[k].lower_bound(n);
  auto l = r;
  l--;
  int pl = (n - (*l) - 1), pr = ((*r) - n - 1), plr = ((*r) - (*l) - 1);
  st[k].insert(n);
  rs += s[n][k];
  rs -= pl * (pl + 1) / 2 * c[k];
  rs -= pr * (pr + 1) / 2 * c[k];
  rs += plr * (plr + 1) / 2 * c[k];
}

void up(int n, int k) {
  rm(n, p[n]);
  p[n] = k;
  ins(n, p[n]);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> d;
  for (int i = 0; i < 26; i++) {
    cin >> c[i];
    st[i].insert(0);
    st[i].insert(d + 1);
  }
  for (int i = 1; i <= d; i++) {
    for (int j = 0; j < 26; j++)
      cin >> s[i][j];
    p[i] = rand() % 26;
    st[p[i]].insert(i);
  }
  rs = cc();
  double k = 300, sc = 250, kt = 0.99915;
  for (int i = 0; i < 5000000; i++) {
    double e1 = rs;
    int n = (rand() % d) + 1, kp = (rand() % 25) + 1;
    int hk = p[n], tk = (hk + kp) % 26;
    up(n, tk);
    int e2 = rs;
    double pb = exp((e2 - e1) / (k * sc));
    if (pb < rand() / (double)RAND_MAX)
      up(n, hk);
    k *= kt;
  }
  for (int i = 1; i <= d; i++)
    cout << p[i] + 1 << '\\n';
  return 0;
}