Problem p02585 (C++) — buggy submission, verdict: Runtime Error

// g++ -std=c++14 test.cpp -o test.out

#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

#define LL long long int
const LL INF = (1LL << 60);
const int INF_INT = 2147483647 - 1e6 - 1;
const LL mod = 1000000007ll;
const int mod_int = 1000000007;

LL N, K;
LL P[5001], C[5001];

LL ans = -INF;

void solve() {
  // 点iから行って戻ってくるまでにかかる操作回数
  vector<LL> loop(N + 1);
  // 点iから行って戻ってくるまでに稼げるスコア
  // もし負なら0としておく
  vector<LL> score_per_loop(N + 1);
  for (int i = 1; i <= N; i++) {
    LL score = 0;
    LL point = i;
    LL numof_loop = 0;
    while (1) {
      point = P[point];
      score += C[point];
      numof_loop++;
      if (i == point)
        break;
    }
    loop[i] = numof_loop;
    score_per_loop[i] = max(0LL, score);
  }

  for (int i = 1; i <= N; i++) {
    // 各点iから初めて、0~K回操作を行った時のスコアの最大値を求める
    LL point = i;
    LL score = 0;
    for (int operation = 1; operation <= min(K, loop[i]); operation++) {
      point = P[point];
      score += C[point];
      ans = max(ans, score + max(0LL, ((K - operation) / loop[i])) *
                                 score_per_loop[i]);
    }
  }
}

int main() {
  cin >> N >> K;
  for (int i = 1; i <= N; i++)
    cin >> P[i];
  for (int i = 1; i <= N; i++)
    cin >> C[i];

  solve();

  cout << ans << endl;
  return 0;
}

Error: -8

Fixed submission:

// g++ -std=c++14 test.cpp -o test.out

#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

#define LL long long int
const LL INF = (1LL << 60);
const int INF_INT = 2147483647 - 1e6 - 1;
const LL mod = 1000000007ll;
const int mod_int = 1000000007;

LL N, K;
LL P[5001];
LL C[5001];

LL ans = -INF;

void solve() {
  // マスiから操作をj回繰り返した時に到達する点nodeとその時の点数scoreを
  // dist[i][j] = (node,score)とおく
  vector<vector<pair<LL, LL>>> dist(N + 2, vector<pair<LL, LL>>(N + 2));
  // また、点iから点iに戻ってくるまでの、1以上の最小の操作回数を
  // loop[i]とおく
  vector<LL> loop(N + 1, -1);
  for (int i = 1; i <= N; i++)
    dist[i][0] = pair<LL, LL>(i, 0);
  for (int i = 1; i <= N; i++) {
    for (int j = 0; j <= N; j++) {
      LL now_node = dist[i][j].first;
      LL now_score = dist[i][j].second;
      LL dist_node = P[now_node];
      LL d_score = C[P[now_node]];
      dist[i][j + 1] = pair<LL, LL>(dist_node, now_score + d_score);
      if (i == dist_node && j + 1 > 0) {
        if (loop[i] == -1)
          loop[i] = j + 1;
      }
    }
  }

  // for(int i=1;i<=N;i++){
  // 	for(int j=0;j<=N;j++){
  // 		cout << i << "->" << j << "->" << dist[i][j].first << ":" <<
  // dist[i][j].second << endl;
  // 	}
  // }

  for (int i = 1; i <= N; i++) {
    // 1ループあたりの得点：dist[i][loop[i]].second
    // cout << i << "->" << dist[i][loop[i]].first << ":" <<
    // dist[i][loop[i]].second << endl;
    if (dist[i][loop[i]].second > 0) {
      LL loop_time = K / loop[i];
      LL quotient = loop_time * dist[i][loop[i]].second;
      for (int j = 0; j <= K % loop_time + 1; j++) {
        ans = max(ans, quotient + dist[i][j].second);
      }
    } else {
      LL loop_time = K / loop[i];
      for (int j = 1; j <= K % loop_time + 1; j++) {
        ans = max(ans, dist[i][j].second);
      }
    }
  }
}

int main() {
  cin >> N >> K;
  for (int i = 1; i <= N; i++)
    cin >> P[i];
  for (int i = 1; i <= N; i++)
    cin >> C[i];

  solve();

  cout << ans << endl;
  return 0;
}