Problem p02816 (C++)

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

using namespace std;

class RollingHash {
private:
  const uint64_t mod = (1ULL << 61) - 1;
  std::vector<uint64_t> hashes, pows;

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

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

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

public:
  template <typename T>
  RollingHash(const T &S, uint64_t 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)
  uint64_t 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<int> 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<int> C(N), D(N);
  for (int i = 0; i < N; i++) {
    C[i] = A[i] ^ A[(i + 1) % N];
    D[i] = B[i] ^ B[(i + 1) % N];
  }
  for (int c : C) {
    C.emplace_back(c);
  }
  RollingHash rhc(C), rhd(D);
  for (int i = 0; i < N; i++) {
    if (rhc.slice(i, i + N) == rhd.slice(0, N)) {
      cout << i << ' ' << (A[i] ^ B[0]) << '\n';
    }
  }
  return 0;
}


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

using namespace std;

class RollingHash {
private:
  const uint64_t mod = (1ULL << 61) - 1;
  std::vector<uint64_t> hashes, pows;

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

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

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

public:
  template <typename T>
  RollingHash(const T &S, uint64_t 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)
  uint64_t 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<int> 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<int> C(N), D(N);
  for (int i = 0; i < N; i++) {
    C[i] = A[i] ^ A[(i + 1) % N];
    D[i] = B[i] ^ B[(i + 1) % N];
  }
  for (int i = 0; i < N; i++) {
    C.emplace_back(C[i]);
  }
  RollingHash rhc(C), rhd(D);
  for (int i = 0; i < N; i++) {
    if (rhc.slice(i, i + N) == rhd.slice(0, N)) {
      cout << i << ' ' << (A[i] ^ B[0]) << '\n';
    }
  }
  return 0;
}