Problem p02247 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i < n; i++)
#define repb(i, a, b) for (int i = a; i >= b; i--)
#define all(a) a.begin(), a.end()
#define int long long
using namespace std;
typedef pair<int, int> P;

struct RollingHash {
  typedef long long ll;
  typedef pair<ll, ll> pll;

  ll base1;
  ll base2;
  ll mod1;
  ll mod2;
  vector<ll> hash1;
  vector<ll> hash2;
  vector<ll> pow1;
  vector<ll> pow2;

  RollingHash()
      : base1(1009), base2(1007), mod1(1000000007), mod2(1000000009) {}

  void init(const string &s) {
    int n = s.size();

    hash1.assign(n + 1, 0);
    hash2.assign(n + 1, 0);
    pow1.assign(n + 1, 1);
    pow2.assign(n + 1, 1);

    for (int i = 0; i < n; i++) {
      hash1[i + 1] = (hash1[i] + s[i]) * base1 % mod1;
      hash2[i + 1] = (hash2[i] + s[i]) * base2 % mod2;
      pow1[i + 1] = pow1[i] * base1 % mod1;
      pow2[i + 1] = pow2[i] * base2 % mod2;
    }
  }
  //[l, r)
  pll get(int l, int r) {
    ll t1 = ((hash1[r] - hash1[l] * pow1[r - l]) % mod1 + mod1) % mod1;
    ll t2 = ((hash2[r] - hash2[l] * pow2[r - l]) % mod2 + mod2) % mod2;
    return make_pair(t1, t2);
  }

  RollingHash::pll concat(pll h1, pll h2, int h2_len) {
    return make_pair((h1.first * pow1[h2_len] + h2.first) % mod1,
                     (h1.second * pow2[h2_len] + h2.second) % mod2);
  }
};

signed main() {
  string s, t;
  cin >> s >> t;
  RollingHash rs, rt;
  rs.init(s);
  rt.init(t);
  P p = rt.get(0, t.size());
  rep(i, 0, s.size() - t.size() + 1) {
    P q = rs.get(i, i + t.size());
    if (p.first == q.first && p.second == q.second) {
      cout << i << endl;
    }
  }
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, a, n) for (int i = a; i < n; i++)
#define repb(i, a, b) for (int i = a; i >= b; i--)
#define all(a) a.begin(), a.end()
#define int long long
using namespace std;
typedef pair<int, int> P;

struct RollingHash {
  typedef long long ll;
  typedef pair<ll, ll> pll;

  ll base1;
  ll base2;
  ll mod1;
  ll mod2;
  vector<ll> hash1;
  vector<ll> hash2;
  vector<ll> pow1;
  vector<ll> pow2;

  RollingHash()
      : base1(1009), base2(1007), mod1(1000000007), mod2(1000000009) {}

  void init(const string &s) {
    int n = s.size();

    hash1.assign(n + 1, 0);
    hash2.assign(n + 1, 0);
    pow1.assign(n + 1, 1);
    pow2.assign(n + 1, 1);

    for (int i = 0; i < n; i++) {
      hash1[i + 1] = (hash1[i] + s[i]) * base1 % mod1;
      hash2[i + 1] = (hash2[i] + s[i]) * base2 % mod2;
      pow1[i + 1] = pow1[i] * base1 % mod1;
      pow2[i + 1] = pow2[i] * base2 % mod2;
    }
  }
  //[l, r)
  pll get(int l, int r) {
    ll t1 = ((hash1[r] - hash1[l] * pow1[r - l]) % mod1 + mod1) % mod1;
    ll t2 = ((hash2[r] - hash2[l] * pow2[r - l]) % mod2 + mod2) % mod2;
    return make_pair(t1, t2);
  }

  RollingHash::pll concat(pll h1, pll h2, int h2_len) {
    return make_pair((h1.first * pow1[h2_len] + h2.first) % mod1,
                     (h1.second * pow2[h2_len] + h2.second) % mod2);
  }
};

signed main() {
  string s, t;
  cin >> s >> t;
  if (s.size() < t.size())
    return 0;
  RollingHash rs, rt;
  rs.init(s);
  rt.init(t);
  P p = rt.get(0, t.size());
  rep(i, 0, s.size() - t.size() + 1) {
    P q = rs.get(i, i + t.size());
    if (p.first == q.first && p.second == q.second) {
      cout << i << endl;
    }
  }
}