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

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define cinf(n, x)                                                             \\
  for (int i = 0; i < (n); i++)                                                \\
    cin >> x[i];
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(), (v).end()
#define LB(a, x) lb(all(a), x) - a.begin()
#define UB(a, x) ub(all(a), x) - a.begin()
#define mod 1000000007
#define FS fixed << setprecision(15)
using namespace std;
typedef long long ll;
const double pi = 3.141592653589793;
template <class T> using V = vector<T>;
using Graph = vector<vector<int>>;
using P = pair<ll, ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

const ll INF = 1e18;
const int mx = 200005;

class UnionFind {
public:
  vector<ll> par, num;

  int find(ll v) { return (par[v] == v) ? v : (par[v] = find(par[v])); }
  explicit UnionFind(ll N) : par(N), num(N, 1) {
    iota(par.begin(), par.end(), 0);
  }
  void unite(ll u, ll v) {
    u = find(u), v = find(v);
    if (u == v)
      return;
    if (num[u] < num[v])
      swap(u, v);
    num[u] += num[v];
    par[v] = u;
  }
  bool same(ll u, ll v) { return find(u) == find(v); }
  bool ispar(ll v) { return v = find(v); }
  ll size(ll v) { return num[find(v)]; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, k;
  cin >> n >> k;
  ll ans = -INF;
  V<ll> p(n), c(n), deg(n, 0);
  V<ll> vv(n);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
    deg[p[i]]++;
    vv[i] = i;
  }
  rep(i, n) {
    cin >> c[i];
    chmax(ans, c[i]);
  }

  V<bool> seen(n, 0);
  V<ll> sum(n, 0);
  V<ll> d(n, -1);
  UnionFind G(n);
  V<P> cy(n);
  sort(all(vv), [&](auto a, auto b) { return deg[a] < deg[b]; });
  rep(i, n) {
    if (seen[vv[i]])
      continue;
    ll kk = vv[i];
    sum[kk] = 0;
    d[kk] = 0;
    seen[kk] = 1;
    while (true) {
      G.unite(kk, p[kk]);
      if (seen[p[kk]]) {
        cy[G.find(kk)] = make_pair(p[kk], kk); // サイクル開始点,1個手前

        break;
      }
      d[p[kk]] = d[kk] + 1;
      sum[p[kk]] = sum[kk] + c[kk];
      seen[p[kk]] = 1;
      kk = p[kk];
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = i; j < n; j++) {
      if (!G.same(i, j))
        continue;

      ll v = cy[G.find(i)].ft, u = cy[G.find(i)].sc;
      if (d[i] < d[v] && d[j] < d[v]) {
        if (abs(d[i] - d[j]) > k)
          continue;
        if (d[i] > d[j])
          chmax(ans, sum[i] - sum[j]);
        else if (d[j] > d[i])
          chmax(ans, sum[j] - sum[i]);
      } else if (d[i] >= d[v] && d[j] >= d[v]) {
        ll cy_sum = sum[u] - sum[v] + c[u];
        ll cy_d = d[u] - d[v] + 1;
        ll mi = i, ma = j;
        if (d[i] > d[j]) {
          swap(mi, ma);
        }
        if (d[ma] - d[mi] <= k && d[ma] - d[mi] > 0)
          chmax(ans, sum[ma] - sum[mi]);
        if (cy_d - (d[ma] - d[mi]) <= k && cy_d - (d[ma] - d[mi]) > 0)
          chmax(ans, cy_sum - (sum[ma] - sum[mi]));
        // chmax(ans,max(sum[ma]-sum[mi],cy_sum-sum[ma]-sum[mi]));
        if (cy_sum > 0) {
          ll X = k - (d[ma] - d[mi]);
          ll Y = k - (cy_d - (d[ma] - d[mi]));
          if (d[ma] - d[mi] <= k && d[ma] - d[mi] > 0)
            chmax(ans, cy_sum * (X / cy_d) + sum[ma] - sum[mi]);
          if (cy_d - (d[ma] - d[mi]) <= k && cy_d - (d[ma] - d[mi]) > 0)
            chmax(ans, cy_sum * (Y / cy_d) + cy_sum - (sum[ma] - sum[mi]));
          // if()
          // chmax(ans,max(cy_sum*(X/cy_d)+sum[ma]-sum[mi],cy_sum*(Y/cy_d)+cy_sum-sum[ma]-sum[mi]));
        }
      } else {
        if (abs(d[i] - d[j]) > k)
          continue;
        ll cy_sum = sum[u] - sum[v] + c[u];
        ll cy_d = d[u] - d[v] + 1;
        ll mi = i, ma = j;
        if (d[i] > d[j]) {
          swap(mi, ma);
        }
        if (abs(d[i] - d[j]) > 0)
          chmax(ans, sum[ma] - sum[mi]);
        if (cy_sum > 0) {
          ll X = k - (d[ma] - d[mi]);
          if (abs(d[i] - d[j]) > 0)
            chmax(ans, sum[ma] - sum[mi] + cy_sum * (X / cy_d));
        }
      }
    }
  }
  cout << ans << endl;
}
// ペナルティ出しても焦らない　ACできると信じろ！！！
// どうしてもわからないときはサンプルで実験　何か見えてくるかも
// 頭で考えてダメなら紙におこせ！！
/*
V,P(大文字)使用不可
乗算などの際にオーバーフローに注意せよ！
(適切にmodをとれ　にぶたんで途中で切り上げろ)
制約をよく読め！
{
    ・全探索できるなら全探索しろ
    ・異常な制約ならそこに注目
}
stringの計算量(扱い)注意
コーナー注意！(特に数値が小さいものについては要検証)
N行出力のときは'¥n'
グリッド上では行先が範囲内におさまるかif文で確認(RE注意)
if文ではちゃんと比較演算子==を使え('='でもエラー出ない)
配列(vector)の大きさが0か1以上かで場合分けせよ(RE注意)
(vector<int> a(m)でm==0というものはできない)
modはなるべく最後に取れ！
doubleを扱うときには(abs)ではなく'fabs'!!!
*/

Error: 0

Fixed submission:

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define cinf(n, x)                                                             \\
  for (int i = 0; i < (n); i++)                                                \\
    cin >> x[i];
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(), (v).end()
#define LB(a, x) lb(all(a), x) - a.begin()
#define UB(a, x) ub(all(a), x) - a.begin()
#define mod 1000000007
#define FS fixed << setprecision(15)
using namespace std;
typedef long long ll;
const double pi = 3.141592653589793;
template <class T> using V = vector<T>;
using Graph = vector<vector<int>>;
using P = pair<ll, ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

const ll INF = 1e18;
const int mx = 200005;

class UnionFind {
public:
  vector<ll> par, num;

  int find(ll v) { return (par[v] == v) ? v : (par[v] = find(par[v])); }
  explicit UnionFind(ll N) : par(N), num(N, 1) {
    iota(par.begin(), par.end(), 0);
  }
  void unite(ll u, ll v) {
    u = find(u), v = find(v);
    if (u == v)
      return;
    if (num[u] < num[v])
      swap(u, v);
    num[u] += num[v];
    par[v] = u;
  }
  bool same(ll u, ll v) { return find(u) == find(v); }
  bool ispar(ll v) { return v = find(v); }
  ll size(ll v) { return num[find(v)]; }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, k;
  cin >> n >> k;
  ll ans = -INF;
  V<ll> p(n), c(n), deg(n, 0);
  V<ll> vv(n);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
    deg[p[k]]++;
    vv[i] = i;
  }
  rep(i, n) {
    cin >> c[i];
    chmax(ans, c[i]);
  }

  V<bool> seen(n, 0);
  V<ll> sum(n, 0);
  V<ll> d(n, -1);
  UnionFind G(n);
  V<P> cy(n);
  sort(all(vv), [&](auto a, auto b) { return deg[a] < deg[b]; });
  rep(i, n) {
    if (seen[vv[i]])
      continue;
    ll k = vv[i];
    sum[k] = 0;
    d[k] = 0;
    while (true) {
      G.unite(k, p[k]);
      if (seen[p[k]]) {
        cy[G.find(k)] = make_pair(p[k], k); // サイクル開始点,1個手前

        break;
      }
      d[p[k]] = d[k] + 1;
      sum[p[k]] = sum[k] + c[k];
      seen[p[k]] = 1;
      k = p[k];
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = i; j < n; j++) {
      if (!G.same(i, j))
        continue;

      ll v = cy[G.find(i)].ft, u = cy[G.find(i)].sc;
      if (d[i] < d[v] && d[j] < d[v]) {
        if (abs(d[i] - d[j]) > k)
          continue;
        if (d[i] > d[j])
          chmax(ans, sum[i] - sum[j]);
        else
          chmax(ans, sum[j] - sum[i]);
      } else if (d[i] >= d[v] && d[j] >= d[v]) {
        ll cy_sum = sum[u] - sum[v] + c[u];
        ll cy_d = d[u] - d[v] + 1;
        ll mi = i, ma = j;
        if (d[i] > d[j]) {
          swap(mi, ma);
        }
        // chmax(ans,max(sum[ma]-sum[mi],cy_sum-sum[ma]-sum[mi]));
        if (cy_sum > 0) {
          ll X = k - (d[ma] - d[mi]);
          ll Y = k - (cy_d - (d[ma] - d[mi]));
          if (d[ma] - d[mi] <= k)
            chmax(ans, cy_sum * (X / cy_d) + sum[ma] - sum[mi]);
          if (cy_d - (d[ma] - d[mi]) <= k)
            chmax(ans, cy_sum * (Y / cy_d) + cy_sum - (sum[ma] - sum[mi]));
          // if()
          // chmax(ans,max(cy_sum*(X/cy_d)+sum[ma]-sum[mi],cy_sum*(Y/cy_d)+cy_sum-sum[ma]-sum[mi]));
        }
      } else {
        if (abs(d[i] - d[j]) > k)
          continue;
        ll cy_sum = sum[u] - sum[v] + c[u];
        ll cy_d = d[u] - d[v] + 1;
        ll mi = i, ma = j;
        if (d[i] > d[j]) {
          swap(mi, ma);
        }
        chmax(ans, sum[ma] - sum[mi]);
        if (cy_sum > 0) {
          ll X = k - (d[ma] - d[mi]);
          chmax(ans, sum[ma] - sum[mi] + cy_sum * (X / cy_d));
        }
      }
    }
  }
  cout << ans << endl;
}
// ペナルティ出しても焦らない　ACできると信じろ！！！
// どうしてもわからないときはサンプルで実験　何か見えてくるかも
// 頭で考えてダメなら紙におこせ！！
/*
V,P(大文字)使用不可
乗算などの際にオーバーフローに注意せよ！
(適切にmodをとれ　にぶたんで途中で切り上げろ)
制約をよく読め！
{
    ・全探索できるなら全探索しろ
    ・異常な制約ならそこに注目
}
stringの計算量(扱い)注意
コーナー注意！(特に数値が小さいものについては要検証)
N行出力のときは'¥n'
グリッド上では行先が範囲内におさまるかif文で確認(RE注意)
if文ではちゃんと比較演算子==を使え('='でもエラー出ない)
配列(vector)の大きさが0か1以上かで場合分けせよ(RE注意)
(vector<int> a(m)でm==0というものはできない)
modはなるべく最後に取れ！
doubleを扱うときには(abs)ではなく'fabs'!!!
*/