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

#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios {
  fast_ios() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  };
} fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end)                                                     \\
  for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \\
  for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) {
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa) {
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template <typename T, typename... Args>
void ndarray(vector<T> &vec, int len, Args... args) {
  vec.resize(len);
  for (auto &v : vec)
    ndarray(v, args...);
}
template <typename T> bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &m, const T q) {
  if (q < m) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return make_pair(l.first + r.first, l.second + r.second);
}
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return make_pair(l.first - r.first, l.second - r.second);
}
#define dbg(x)                                                                 \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds; // find_by_order(), order_of_key()
template<typename TK> using pbds_set = tree<TK, null_type, less<TK>,
rb_tree_tag, tree_order_statistics_node_update>; template<typename TK, typename
TV> using pbds_map = tree<TK, TV, less<TK>, rb_tree_tag,
tree_order_statistics_node_update>;
*/

// Binary lifting / `Doubling`
// Complexity: O(NlogN) precalculation / O(logN) per query
// <https://atcoder.jp/contests/arc060/submissions/7039451>
struct BinaryLifting {
  int N, INVALID, lgD;
  std::vector<std::vector<int>> mat;
  BinaryLifting() : N(0), lgD(0) {}
  BinaryLifting(const std::vector<int> &vec_nxt, int INVALID = -1, int lgd = 0)
      : N(vec_nxt.size()), INVALID(INVALID), lgD(lgd) {
    while ((1LL << lgD) < N)
      lgD++;
    mat.assign(lgD, std::vector<int>(N, INVALID));
    mat[0] = vec_nxt;
    for (int i = 0; i < N; i++)
      if (mat[0][i] < 0 or mat[0][i] >= N)
        mat[0][i] = INVALID;
    for (int d = 0; d < lgD - 1; d++) {
      for (int i = 0; i < N; i++)
        if (mat[d][i] != INVALID)
          mat[d + 1][i] = mat[d][mat[d][i]];
    }
  }
  int kth_next(int now, long long k) {
    if (k >= (1LL << lgD))
      exit(8);
    for (int d = 0; k and now != INVALID; d++, k >>= 1)
      if (k & 1)
        now = mat[d][now];
    return now;
  }

  // Distance from l to [r, \\infty)
  // Requirement: mat[0][i] > i for all i (monotone increasing)
  int distance(int l, int r) {
    if (l >= r)
      return 0;
    int ret = 0;
    for (int d = lgD - 1; d >= 0; d--) {
      if (mat[d][l] < r and mat[d][l] != INVALID)
        ret += 1 << d, l = mat[d][l];
    }
    if (mat[0][l] == INVALID or mat[0][l] >= r)
      return ret + 1;
    else
      return -1; // Unable to reach
  }
};

int main() {
  int N;
  long long K;
  cin >> N >> K;
  vector<int> A(N);
  cin >> A;
  for (auto &a : A)
    a--;
  BinaryLifting bl(A, -1, 62);
  cout << bl.kth_next(0, K) + 1 << '\\n';
}


Error: 8

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios {
  fast_ios() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  };
} fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end)                                                     \\
  for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end)                                                    \\
  for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) {
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) {
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa) {
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) {
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template <typename T, typename... Args>
void ndarray(vector<T> &vec, int len, Args... args) {
  vec.resize(len);
  for (auto &v : vec)
    ndarray(v, args...);
}
template <typename T> bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &m, const T q) {
  if (q < m) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return make_pair(l.first + r.first, l.second + r.second);
}
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return make_pair(l.first - r.first, l.second - r.second);
}
#define dbg(x)                                                                 \\
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds; // find_by_order(), order_of_key()
template<typename TK> using pbds_set = tree<TK, null_type, less<TK>,
rb_tree_tag, tree_order_statistics_node_update>; template<typename TK, typename
TV> using pbds_map = tree<TK, TV, less<TK>, rb_tree_tag,
tree_order_statistics_node_update>;
*/

// Binary lifting / `Doubling`
// Complexity: O(NlogN) precalculation / O(logN) per query
// <https://atcoder.jp/contests/arc060/submissions/7039451>
struct BinaryLifting {
  int N, INVALID, lgD;
  std::vector<std::vector<int>> mat;
  BinaryLifting() : N(0), lgD(0) {}
  BinaryLifting(const std::vector<int> &vec_nxt, int INVALID = -1, int lgd = 0)
      : N(vec_nxt.size()), INVALID(INVALID), lgD(lgd) {
    while ((1 << lgD) < N)
      lgD++;
    mat.assign(lgD, std::vector<int>(N, INVALID));
    mat[0] = vec_nxt;
    for (int i = 0; i < N; i++)
      if (mat[0][i] < 0 or mat[0][i] >= N)
        mat[0][i] = INVALID;
    for (int d = 0; d < lgD - 1; d++) {
      for (int i = 0; i < N; i++)
        if (mat[d][i] != INVALID)
          mat[d + 1][i] = mat[d][mat[d][i]];
    }
  }
  int kth_next(int now, int k) {
    if (k >= (1 << lgD))
      exit(8);
    for (int d = 0; k and now != INVALID; d++, k >>= 1)
      if (k & 1)
        now = mat[d][now];
    return now;
  }

  // Distance from l to [r, \\infty)
  // Requirement: mat[0][i] > i for all i (monotone increasing)
  int distance(int l, int r) {
    if (l >= r)
      return 0;
    int ret = 0;
    for (int d = lgD - 1; d >= 0; d--) {
      if (mat[d][l] < r and mat[d][l] != INVALID)
        ret += 1 << d, l = mat[d][l];
    }
    if (mat[0][l] == INVALID or mat[0][l] >= r)
      return ret + 1;
    else
      return -1; // Unable to reach
  }
};

int main() {
  int N, K;
  cin >> N >> K;
  vector<int> A(N);
  cin >> A;
  for (auto &a : A)
    a--;
  BinaryLifting bl(A, -1, 31);
  cout << bl.kth_next(0, K) + 1 << '\\n';
}