Problem p01726 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

const ll mod[] = {999999937, 1000000007}, base = 10000103;

struct RollingHash {
  int n;
  vector<ll> hs[2], pw[2];
  RollingHash(){};
  RollingHash(const string &s) {
    n = s.size();
    REP(i, 2) {
      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) {
    return (hash(l1, r1, 0) == hash(l2, r2, 0)) &&
           (hash(l1, r1, 1) == hash(l2, r2, 1));
  }
};

int main() {
  string s, t;
  cin >> s >> t;
  RollingHash rhs(s), rht(t);
  map<pii, int> mp;
  REP(i, s.size() - t.size() + 1) {
    int a = rhs.hash(i, i + t.size(), 0), b = rhs.hash(i, i + t.size(), 1);
    pii p = pii(a, b);
    mp[p]++;
  }
  ll ans = 0;
  REP(i, t.size()) {
    ll a = rht.hash(0, t.size(), 0), b = rht.hash(0, t.size(), 1);
    a = (a - t[i] * rht.pw[0][t.size() - i - 1] + mod[0] * 1000) % mod[0];
    b = (b - t[i] * rht.pw[1][t.size() - i - 1] + mod[1] * 1000) % mod[1];
    REP(j, 26) {
      char c = 'a' + j;
      if (c == t[i])
        continue;
      int pa = (a + c * rht.pw[0][t.size() - i - 1]) % mod[0],
          pb = (b + c * rht.pw[1][t.size() - i - 1]) % mod[1];
      pii p(pa, pb);
      if (mp.count(p))
        ans += mp[p];
    }
    REP(j, 26) {
      char c = 'A' + j;
      if (c == t[i])
        continue;
      int pa = (a + c * rht.pw[0][t.size() - i - 1]) % mod[0],
          pb = (b + c * rht.pw[1][t.size() - i - 1]) % mod[1];
      pii p(pa, pb);
      if (mp.count(p))
        ans += mp[p];
    }
  }
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

typedef vector<int> SuffixArray;
int n, k;
vi rnk, tmp;

bool comp_sa(const int i, const int j) {
  if (rnk[i] != rnk[j])
    return rnk[i] < rnk[j];
  else {
    int ri = i + k <= n ? rnk[i + k] : -1;
    int rj = j + k <= n ? rnk[j + k] : -1;
    return ri < rj;
  }
}

SuffixArray construct_sa(const string &s) {
  n = s.size();
  SuffixArray sa(n + 1);
  rnk.resize(n + 1), tmp.resize(n + 1);
  REP(i, n + 1) {
    sa[i] = i;
    if (i == n)
      rnk[i] = -1;
    else
      rnk[i] = s[i];
  }
  for (k = 1; k <= n; k *= 2) {
    sort(ALL(sa), comp_sa);
    tmp[sa[0]] = 0;
    REP(i, n) tmp[sa[i + 1]] = tmp[sa[i]] + (comp_sa(sa[i], sa[i + 1]) ? 1 : 0);
    rnk = tmp;
  }
  return sa;
}

bool search(const string &s, const string &t, const SuffixArray &sa) {
  int l = 0, r = s.size();
  while (r - l > 1) {
    int mid = (r + l) / 2;
    if (s.compare(sa[mid], t.size(), t) < 0)
      l = mid;
    else
      r = mid;
  }
  return s.compare(sa[r], t.size(), t) == 0;
}

int lower_bound(const string &s, const string &t, const SuffixArray &sa) {
  int l = 0, r = s.size() + 1;
  while (r - l > 1) {
    int mid = (r + l) / 2;
    if (s.compare(sa[mid], t.size(), t) < 0)
      l = mid;
    else
      r = mid;
  }
  return r;
}

int upper_bound(const string &s, const string &t, const SuffixArray &sa) {
  int l = 0, r = s.size() + 1;
  while (r - l > 1) {
    int mid = (r + l) / 2;
    if (s.compare(sa[mid], t.size(), t) <= 0)
      l = mid;
    else
      r = mid;
  }
  return r;
}

int main() {
  string s, t;
  cin >> s >> t;
  SuffixArray sa = construct_sa(s);
  ll ans = 0;
  REP(i, t.size()) {
    string tmp = t;
    REP(j, 26) {
      char c = 'a' + j;
      if (c == t[i])
        continue;
      tmp[i] = c;
      ans += upper_bound(s, tmp, sa) - lower_bound(s, tmp, sa);
    }
  }
  cout << ans << endl;
  return 0;
}