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

#include <iostream>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; ++i)
using namespace std;
using ll = long long;

class KMP {
public:
  string s;
  string t;
  vector<int> T;
  KMP(string _s, string _t) : s(_s), t(_t), T(s.size()) {}

  void table() {
    int i = 2;
    int j = 0;
    T[0] = -1;
    T[1] = 0;
    while (i < t.size()) {
      if (t[i - 1] == t[j]) {
        T[i] = ++j;
        ++i;
      } else if (j > 0) {
        j = T[j];
      } else {
        T[i] = 0;
        i++;
      }
    }
  }

  int run(int st) {
    int m = st;
    int i = 0;
    //       cout << s.substr(m) << endl;

    while (m + i < s.size()) {
      if (t[i] == s[m + i]) {
        i++;
        if (i == t.size()) {
          return m;
        }
      } else {
        m = m + i - T[i];
        if (i > 0)
          i = T[i];
      }
    }
    return s.size();
  }
};

const int MAX = 500000, MS = 2;
const ll mod[] = {999999937LL, 1000000007LL}, base = 9973;
class RollingHash {
public:
  int n;
  vector<ll> hs[MS], pw[MS];
  RollingHash() {}
  RollingHash(const string &s) {
    n = s.size();
    rep(i, MS) {
      hs[i].assign(n + 1, 0);
      pw[i].assign(n + 1, 0);
      hs[i][0] = 0;
      pw[i][0] = 1;
      rep(j, n) {
        pw[i][j + 1] = pw[i][j] * base % mod[i];
        hs[i][j + 1] = (hs[i][j] * base + s[j]) % mod[i];
      }
    }
  }
  ll hash(int l, int r, int i) {
    if (r > n)
      return -1;
    return ((hs[i][r] - hs[i][l] * pw[i][r - l]) % mod[i] + mod[i]) % mod[i];
  }
  bool match(int l1, int r1, int l2, int r2) {
    bool ret = 1;
    rep(i, MS) { ret &= hash(l1, r1, i) == hash(l2, r2, i); }
    return ret;
  }

  bool match(int l, int r, ll h[]) {
    bool ret = 1;
    rep(i, MS) ret &= hash(l, r, i) == h[i];
    return ret;
  }
};

int main(void) {
  string t;
  string p;
  cin >> t;
  cin >> p;
  // t = 10^6
  // p = 10^4

  RollingHash rht(t);
  RollingHash rhp(p);
  ll ps[MS];
  rep(j, MS) { ps[j] = rhp.hash(0, p.size(), j); }

  rep(i, t.size()) {
    bool ok = true;
    rep(j, MS) { ok &= rht.hash(i, i + p.size(), j) == ps[j]; }
    if (ok) {
      cout << i << endl;
    }
  }

  return 0;
}

Error: 0

Fixed submission:

#include <iostream>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; ++i)
using namespace std;
using ll = long long;

class KMP {
public:
  string s;
  string t;
  vector<int> T;
  KMP(string _s, string _t) : s(_s), t(_t), T(s.size()) {}

  void table() {
    int i = 2;
    int j = 0;
    T[0] = -1;
    T[1] = 0;
    while (i < t.size()) {
      if (t[i - 1] == t[j]) {
        T[i] = ++j;
        ++i;
      } else if (j > 0) {
        j = T[j];
      } else {
        T[i] = 0;
        i++;
      }
    }
  }

  int run(int st) {
    int m = st;
    int i = 0;
    //       cout << s.substr(m) << endl;

    while (m + i < s.size()) {
      if (t[i] == s[m + i]) {
        i++;
        if (i == t.size()) {
          return m;
        }
      } else {
        m = m + i - T[i];
        if (i > 0)
          i = T[i];
      }
    }
    return s.size();
  }
};

const int MAX = 500000, MS = 2;
const ll mod[] = {999999937LL, 1000000007LL}, base = 9973;
class RollingHash {
public:
  int n;
  vector<ll> hs[MS], pw[MS];
  RollingHash() {}
  RollingHash(const string &s) {
    n = s.size();
    rep(i, MS) {
      hs[i].assign(n + 1, 0);
      pw[i].assign(n + 1, 0);
      hs[i][0] = 0;
      pw[i][0] = 1;
      rep(j, n) {
        pw[i][j + 1] = pw[i][j] * base % mod[i];
        hs[i][j + 1] = (hs[i][j] * base + s[j]) % mod[i];
      }
    }
  }
  ll hash(int l, int r, int i) {
    return ((hs[i][r] - hs[i][l] * pw[i][r - l]) % mod[i] + mod[i]) % mod[i];
  }
  bool match(int l1, int r1, int l2, int r2) {
    bool ret = 1;
    rep(i, MS) { ret &= hash(l1, r1, i) == hash(l2, r2, i); }
    return ret;
  }

  bool match(int l, int r, ll h[]) {
    bool ret = 1;
    rep(i, MS) ret &= hash(l, r, i) == h[i];
    return ret;
  }
};

int main(void) {
  string t;
  string p;
  cin >> t;
  cin >> p;
  // t = 10^6
  // p = 10^4

  RollingHash rh(t + p);

  rep(i, t.size() - p.size() + 1) {
    if (rh.match(i, i + p.size(), t.size(), t.size() + p.size())) {
      cout << i << endl;
    }
  }

  return 0;
}