Problem p02816 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;
using u64 = std::uint_fast64_t;

class RollingHash {
private:
  using u64 = std::uint_fast64_t;

  const u64 mod = ((u64)1 << 61) - 1;
  std::vector<u64> hashes, pows;

  inline u64 add(u64 a, u64 b) const {
    a += b;
    if (a >= mod)
      a -= mod;
    return a;
  }

  inline u64 sub(u64 a, u64 b) const {
    if (a < b)
      a += mod;
    a -= b;
    return a;
  }

  inline u64 mul(u64 a, u64 b) const {
    u64 ah = a >> 31, al = a & (((u64)1 << 31) - 1), bh = b >> 31,
        bl = b & (((u64)1 << 31) - 1), m = ah * bl + al * bh,
        v = (ah * bh << 1) + (m >> 30) + ((m & (((u64)1 << 30) - 1)) << 31) +
            al * bl;
    v = (v & (((u64)1 << 61) - 1)) + (v >> 61);
    return v;
  }

public:
  template <typename T>
  RollingHash(const T &S, u64 base = 10007)
      : hashes(S.size() + 1, 0), pows(S.size() + 1, 0) {
    pows[0] = 1;
    for (size_t i = 0; i < S.size(); i++) {
      pows[i + 1] = mul(pows[i], base);
      hashes[i + 1] = add(mul(hashes[i], base), S[i]);
    }
  }

  // S[r, l)
  u64 slice(int l, int r) const {
    return sub(hashes[r], mul(hashes[l], pows[r - l]));
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N;
  cin >> N;
  vector<u64> A(N), B(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  for (int i = 0; i < N; i++) {
    cin >> B[i];
  }

  vector<u64> S(N), T(N);
  for (int i = 0; i < N; i++) {
    S[i] = A[i] ^ A[(i + 1) % N];
    T[i] = B[i] ^ B[(i + 1) % N];
  }
  copy(S.begin(), S.end(), back_inserter(S));

  RollingHash rhs(S), rht(T);
  for (int i = 0; i < N; i++) {
    if (rhs.slice(i, i + N) == rht.slice(0, N)) {
      cout << i << " " << (A[i] ^ B[0]) << '\n';
    }
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;
using u64 = std::uint_fast64_t;

class RollingHash {
private:
  using u64 = std::uint_fast64_t;

  const u64 mod = ((u64)1 << 61) - 1;
  std::vector<u64> hashes, pows;

  inline u64 add(u64 a, u64 b) const {
    a += b;
    if (a >= mod)
      a -= mod;
    return a;
  }

  inline u64 sub(u64 a, u64 b) const {
    if (a < b)
      a += mod;
    a -= b;
    return a;
  }

  inline u64 mul(u64 a, u64 b) const {
    u64 ah = a >> 31, al = a & (((u64)1 << 31) - 1), bh = b >> 31,
        bl = b & (((u64)1 << 31) - 1), m = ah * bl + al * bh,
        v = (ah * bh << 1) + (m >> 30) + ((m & (((u64)1 << 30) - 1)) << 31) +
            al * bl;
    v = (v & (((u64)1 << 61) - 1)) + (v >> 61);
    return v;
  }

public:
  template <typename T>
  RollingHash(const T &S, u64 base = 10007)
      : hashes(S.size() + 1, 0), pows(S.size() + 1, 0) {
    pows[0] = 1;
    for (size_t i = 0; i < S.size(); i++) {
      pows[i + 1] = mul(pows[i], base);
      hashes[i + 1] = add(mul(hashes[i], base), S[i]);
    }
  }

  // S[r, l)
  u64 slice(int l, int r) const {
    return sub(hashes[r], mul(hashes[l], pows[r - l]));
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int N;
  cin >> N;
  vector<u64> A(N), B(N);
  for (int i = 0; i < N; i++) {
    cin >> A[i];
  }
  for (int i = 0; i < N; i++) {
    cin >> B[i];
  }

  vector<u64> S(N), T(N);
  for (int i = 0; i < N; i++) {
    S[i] = A[i] ^ A[(i + 1) % N];
    T[i] = B[i] ^ B[(i + 1) % N];
  }
  for (int i = 0; i < N; i++) {
    S.emplace_back(S[i]);
  }

  RollingHash rhs(S), rht(T);
  for (int i = 0; i < N; i++) {
    if (rhs.slice(i, i + N) == rht.slice(0, N)) {
      cout << i << " " << (A[i] ^ B[0]) << '\n';
    }
  }

  return 0;
}