Problem p02618 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#include <time.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i, n, m) for (int i = (n); i <= (m); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
using Graph = vector<vector<int>>;

int d;
int c[26];
int s[365][26];

map<int, int> exist[26];
int sum[26];

int sigma(int x) { return (x + 1) * x / 2; }

void make_sum(int i) {
  sum[i] = 0;
  int last = -1;
  for (auto x : exist[i]) {
    sum[i] += sigma(x.first - last - 1);
    last = x.first;
  }
  sum[i] += sigma(d - 1 - last);
  /*cout << "i=" << (i+1) << ":";
    for (auto x:exist[i]) cout << x << ",";
    cout <<sum[i]<< endl;*/
}

void sol_init(int order[]) {
  rep(i, 26) exist[i].clear();
  rep(j, d) exist[order[j]][j] = 1;
  rep(i, 26) make_sum(i);
}

int sol_val(int order[]) {
  int ans = 0;
  rep(j, d) ans += s[j][order[j]];
  rep(i, 26) ans -= c[i] * sum[i];
  return ans;
}

int diff(int order[], int j, int x) {
  int i = order[j];
  int ans = -s[j][i] + s[j][x];

  int tmp = sum[i];
  exist[i].erase(j);
  make_sum(i);
  ans -= c[i] * (sum[i] - tmp);
  sum[i] = tmp;
  exist[i][j] = 1;

  tmp = sum[x];
  exist[x][j] = 1;
  make_sum(x);
  ans -= c[x] * (sum[x] - tmp);
  sum[x] = tmp;
  exist[x].erase(j);

  return ans;
}

int diff_1opt(int order[], int j) {
  int max = 0;
  int max_i = order[j];
  rep(i, 26) {
    if (i == order[j])
      continue;
    int ans = s[j][i];
    int tmp = sum[i];
    exist[i][j] = 1;
    make_sum(i);
    ans -= c[i] * (sum[i] - tmp);
    sum[i] = tmp;
    exist[i].erase(j);

    if (max < ans) {
      max = ans;
      max_i = i;
    }
  }
  return max_i;
}

int main() {
  clock_t start = clock();
  cin >> d;
  rep(i, 26) cin >> c[i];
  rep(j, d) { rep(i, 26) cin >> s[j][i]; }

  int order[d];
  rep(j, d) {
    int max = s[j][0], max_i = 0;
    rep(i, 26) {
      if (max < s[j][i]) {
        max = s[j][i];
        max_i = i;
      }
    }
    order[j] = max_i;
    // cout << (max_i+1) << endl;
  }
  sol_init(order);
  // cout << sol_val(order) << endl;

  int best_val = sol_val(order);
  int best_order[d];
  memcpy(best_order, order, sizeof(int) * d);
  int j = 0, last_j = 0;
  while (j < d) {
    clock_t now = clock();
    if ((now - start) / CLOCKS_PER_SEC > 1.9)
      break;
    int opt = diff_1opt(order, (last_j + j) % d);
    int dif = diff(order, (last_j + j) % d, opt);
    if (dif > -100) {
      order[(last_j + j) % d] = opt;
      sol_init(order);
      // cout << last_j+j << "->" << opt+1 << "=" << sol_val(order) << endl;
      last_j = (last_j + j) % d;
      j = 0;

      if (best_val < sol_val(order)) {
        best_val = sol_val(order);
        memcpy(best_order, order, sizeof(int) * d);
      }
    }
    j++;
  }
  for (auto x : best_order)
    cout << (x + 1) << endl;
  // cout << best_val << endl;
}


Fixed submission:
#include <bits/stdc++.h>
#include <time.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i, n, m) for (int i = (n); i <= (m); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
using Graph = vector<vector<int>>;

int d;
int c[26];
int s[365][26];

map<int, int> exist[26];
int sum[26];

int sigma(int x) { return (x + 1) * x / 2; }

void make_sum(int i) {
  sum[i] = 0;
  int last = -1;
  for (auto x : exist[i]) {
    sum[i] += sigma(x.first - last - 1);
    last = x.first;
  }
  sum[i] += sigma(d - 1 - last);
  /*cout << "i=" << (i+1) << ":";
    for (auto x:exist[i]) cout << x << ",";
    cout <<sum[i]<< endl;*/
}

void sol_init(int order[]) {
  rep(i, 26) exist[i].clear();
  rep(j, d) exist[order[j]][j] = 1;
  rep(i, 26) make_sum(i);
}

int sol_val(int order[]) {
  int ans = 0;
  rep(j, d) ans += s[j][order[j]];
  rep(i, 26) ans -= c[i] * sum[i];
  return ans;
}

int diff(int order[], int j, int x) {
  int i = order[j];
  int ans = -s[j][i] + s[j][x];

  int tmp = sum[i];
  exist[i].erase(j);
  make_sum(i);
  ans -= c[i] * (sum[i] - tmp);
  sum[i] = tmp;
  exist[i][j] = 1;

  tmp = sum[x];
  exist[x][j] = 1;
  make_sum(x);
  ans -= c[x] * (sum[x] - tmp);
  sum[x] = tmp;
  exist[x].erase(j);

  return ans;
}

int diff_1opt(int order[], int j) {
  int max = 0;
  int max_i = order[j];
  rep(i, 26) {
    if (i == order[j])
      continue;
    int ans = s[j][i];
    int tmp = sum[i];
    exist[i][j] = 1;
    make_sum(i);
    ans -= c[i] * (sum[i] - tmp);
    sum[i] = tmp;
    exist[i].erase(j);

    if (max < ans) {
      max = ans;
      max_i = i;
    }
  }
  return max_i;
}

int main() {
  clock_t start = clock();
  cin >> d;
  rep(i, 26) cin >> c[i];
  rep(j, d) { rep(i, 26) cin >> s[j][i]; }

  int order[d];
  rep(j, d) {
    int max = s[j][0], max_i = 0;
    rep(i, 26) {
      if (max < s[j][i]) {
        max = s[j][i];
        max_i = i;
      }
    }
    order[j] = max_i;
    // cout << (max_i+1) << endl;
  }
  sol_init(order);
  // cout << sol_val(order) << endl;

  int best_val = sol_val(order);
  int best_order[d];
  memcpy(best_order, order, sizeof(int) * d);
  int j = 0, last_j = 0;
  while (j < d) {
    clock_t now = clock();
    if ((double)(now - start) / CLOCKS_PER_SEC > 1.9)
      break;
    int opt = diff_1opt(order, (last_j + j) % d);
    int dif = diff(order, (last_j + j) % d, opt);
    if (dif > -100) {
      order[(last_j + j) % d] = opt;
      sol_init(order);
      // cout << last_j+j << "->" << opt+1 << "=" << sol_val(order) << endl;
      last_j = (last_j + j) % d;
      j = 0;

      if (best_val < sol_val(order)) {
        best_val = sol_val(order);
        memcpy(best_order, order, sizeof(int) * d);
      }
    }
    j++;
  }
  for (auto x : best_order)
    cout << (x + 1) << endl;
  // cout << best_val << endl;
}