Problem p02585 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> p(1 + n);
  vector<ll> c(1 + n);
  for (int i = 1; i <= n; ++i)
    cin >> p[i];
  for (int i = 1; i <= n; ++i)
    cin >> c[i];

  // ループのスコア計算は前処理
  vector<ll> loop_score(1 + n);
  vector<int> loop_size(1 + n);
  vector<bool> loop_checked(1 + n, false);
  for (int start_point = 1; start_point <= n; start_point++) {
    if (!loop_checked[start_point]) {
      ll score = c[start_point];
      int loop_size_tmp = 1;
      for (int point = p[start_point]; point != start_point; point = p[point]) {
        score += c[point];
        loop_size_tmp += 1;
      }
      loop_score[start_point] = score;
      loop_size[start_point] = loop_size_tmp;
      loop_checked[start_point] = true;
      for (int point = p[start_point]; point != start_point; point = p[point]) {
        loop_score[point] = score;
        loop_size[point] = loop_size_tmp;
        loop_checked[point] = true;
      }
    }
  }

  ll ans = -1e10;
  for (int start_point = 1; start_point <= n; start_point++) {
    // 最後の2周弱はケチらず数える
    ll current_score = 0, max_score = -1e10;
    int k_tmp = k, point = start_point;
    if (loop_size[start_point] * 2 <= k && loop_score[start_point] > 0) {
      current_score =
          (k / loop_size[start_point] - 1) * loop_score[start_point];
      max_score = current_score;
      k_tmp = k - (k / loop_size[start_point] - 1) * loop_size[start_point];
    }
    for (int i = 0; i < k_tmp; ++i) {
      point = p[point];
      current_score += c[point];
      max_score = max(current_score, max_score);
    }
    ans = max(ans, max_score);
  }
  cout << ans;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> p(1 + n);
  vector<ll> c(1 + n);
  for (int i = 1; i <= n; ++i)
    cin >> p[i];
  for (int i = 1; i <= n; ++i)
    cin >> c[i];

  // ループのスコア計算は前処理
  vector<ll> loop_score(1 + n);
  vector<int> loop_size(1 + n);
  vector<bool> loop_checked(1 + n, false);
  for (int start_point = 1; start_point <= n; start_point++) {
    if (!loop_checked[start_point]) {
      ll score = c[start_point];
      int loop_size_tmp = 1;
      for (int point = p[start_point]; point != start_point; point = p[point]) {
        score += c[point];
        loop_size_tmp += 1;
      }
      loop_score[start_point] = score;
      loop_size[start_point] = loop_size_tmp;
      loop_checked[start_point] = true;
      for (int point = p[start_point]; point != start_point; point = p[point]) {
        loop_score[point] = score;
        loop_size[point] = loop_size_tmp;
        loop_checked[point] = true;
      }
    }
  }

  ll ans = -1e10;
  for (int start_point = 1; start_point <= n; start_point++) {
    // 最後の2周弱はケチらず数える
    ll current_score = 0, max_score = -1e10;
    int k_tmp = k, point = start_point;
    if (loop_size[start_point] * 2 <= k) {
      if (loop_score[start_point] > 0) {
        current_score =
            (k / loop_size[start_point] - 1) * loop_score[start_point];
        max_score = current_score;
      }
      k_tmp = k - (k / loop_size[start_point] - 1) * loop_size[start_point];
    }
    for (int i = 0; i < k_tmp; ++i) {
      point = p[point];
      current_score += c[point];
      max_score = max(current_score, max_score);
    }
    ans = max(ans, max_score);
  }
  cout << ans;
  return 0;
}