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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

using ll = int;
using ha = pair<ll, ll>;
struct RollingHash {
  static const ll mul0 = 10009, mul1 = 10007;
  static const ll add0 = 1000010007, add1 = 1003333331;
  size_t len;
  // vector<ll> hash_, hash2_;
  vector<ha> hash_;
  // static vector<ll> pmo_, pmo2_;
  static vector<ha> pmo_;
  void init(const vector<ll> &s) {
    len = s.size();
    hash_.resize(len + 1);
    hash_[0] = make_pair(0, 0);

    if (pmo_.empty()) {
      pmo_.push_back(make_pair(1, 1));
    }
    while (pmo_.size() <= len) {
      pmo_.push_back(
          make_pair(pmo_.back().first * mul0, pmo_.back().second * mul1));
    }
    for (unsigned int i = 0; i < len; ++i) {
      hash_[i + 1] = make_pair((hash_[i].first * mul0 + s[i]),
                               (hash_[i].second * mul1 + s[i]));
    }
    return;
  }
  void init(const string &s) {
    vector<ll> v;
    for (char c : s) {
      v.push_back(c);
    }
    init(v);
  }
  ha hash(const int l, const int r) const { // s[l..r]
    return make_pair(
        hash_[r + 1].first - hash_[l].first * pmo_[r + 1 - l].first,
        hash_[r + 1].second - hash_[l].second * pmo_[r + 1 - l].second);
  }
  ha hash() const { // s[all]
    return hash(0, len - 1);
  }

  // hash????????????
  static ha concat(const ha L, const ha R, const int RLength) { // hash(L+R)
    return make_pair((R.first + L.first * pmo_[RLength].first),
                     (R.second + L.second * pmo_[RLength].second));
  }

  // index????????????from??????to??????????????????????????????
  ha get_changed_hash(const int index, const ll from, const ll to) const {
    const ha p(hash());
    return make_pair(p.first + (to - from) * pmo_[len - index - 1].first,
                     p.second + (to - from) * pmo_[len - index - 1].second);
  }
};
vector<ha> RollingHash::pmo_;

int main() {
  string s;
  cin >> s;
  RollingHash base;
  base.init(s);
  RollingHash sub;
  {
    string t;
    cin >> t;
    sub.init(t);
  }
  vector<bool> oks(base.len - sub.len + 1, false);
  {
    vector<ha> ha_set;
    for (int i = 0; i < s.size(); ++i) {
      for (int a = 'a'; a <= 'z'; ++a) {
        if (s[i] != a) {
          ha ahash = base.get_changed_hash(i, s[i], a);
          ha_set.emplace_back(ahash);
        }
      }
    }
    sort(ha_set.begin(), ha_set.end());
    for (int l = 0; l <= base.len - sub.len; ++l) {
      ha nh = RollingHash::concat(base.hash(0, l - 1), sub.hash(), sub.len);
      nh = RollingHash::concat(nh, base.hash(sub.len + l, base.len - 1),
                               base.len - sub.len - l);
      if (binary_search(ha_set.begin(), ha_set.end(), nh))
        oks[l] = true;
    }
    ha_set.clear();
  }
  {
    vector<ha> ha_set;
    for (int i = 0; i < s.size(); ++i) {
      for (int a = 'A'; a <= 'Z'; ++a) {
        if (s[i] != a) {
          ha ahash = base.get_changed_hash(i, s[i], a);
          ha_set.emplace_back(ahash);
        }
      }
    }
    sort(ha_set.begin(), ha_set.end());
    for (int l = 0; l <= base.len - sub.len; ++l) {
      ha nh = RollingHash::concat(base.hash(0, l - 1), sub.hash(), sub.len);
      nh = RollingHash::concat(nh, base.hash(sub.len + l, base.len - 1),
                               base.len - sub.len - l);
      if (binary_search(ha_set.begin(), ha_set.end(), nh))
        oks[l] = true;
    }
  }
  int ans = count(oks.begin(), oks.end(), true);
  cout << ans << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt"

using ll = int;
using ha = pair<ll, ll>;
struct RollingHash {
  static const ll mul0 = 10009, mul1 = 10007;
  static const ll add0 = 1000010007, add1 = 1003333331;
  size_t len;
  // vector<ll> hash_, hash2_;
  vector<ha> hash_;
  // ha hash_[300010];
  // static vector<ll> pmo_, pmo2_;
  static vector<ha> pmo_;
  void init(const vector<ll> &s) {
    len = s.size();
    hash_.resize(len + 1);
    hash_[0] = make_pair(0, 0);

    if (pmo_.empty()) {
      pmo_.push_back(make_pair(1, 1));
    }
    while (pmo_.size() <= len) {
      pmo_.push_back(
          make_pair(pmo_.back().first * mul0, pmo_.back().second * mul1));
    }
    for (unsigned int i = 0; i < len; ++i) {
      hash_[i + 1] = make_pair((hash_[i].first * mul0 + s[i]),
                               (hash_[i].second * mul1 + s[i]));
    }
    return;
  }
  void init(const string &s) {
    vector<ll> v;
    for (char c : s) {
      v.push_back(c);
    }
    init(v);
  }
  ha hash(const int l, const int r) const { // s[l..r]
    return make_pair(
        hash_[r + 1].first - hash_[l].first * pmo_[r + 1 - l].first,
        hash_[r + 1].second - hash_[l].second * pmo_[r + 1 - l].second);
  }
  ha hash() const { // s[all]
    return hash(0, len - 1);
  }

  // hash????????????
  static ha concat(const ha L, const ha R, const int RLength) { // hash(L+R)
    return make_pair((R.first + L.first * pmo_[RLength].first),
                     (R.second + L.second * pmo_[RLength].second));
  }

  // index????????????from??????to??????????????????????????????
  ha get_changed_hash(const int index, const ll from, const ll to) const {
    const ha p(hash());
    return make_pair(p.first + (to - from) * pmo_[len - index - 1].first,
                     p.second + (to - from) * pmo_[len - index - 1].second);
  }
};
vector<ha> RollingHash::pmo_;

vector<ha> ha_set;
int main() {
  string s;
  cin >> s;
  RollingHash base;
  base.init(s);
  for (int i = 0; i < s.size(); ++i) {
    for (int a = 'A'; a <= 'z'; ++a) {
      if (a == 'Z' + 1)
        a = 'a';
      if (s[i] != a) {
        ha ahash = base.get_changed_hash(i, s[i], a);
        ha_set.emplace_back(ahash);
      }
    }
  }
  sort(ha_set.begin(), ha_set.end());
  RollingHash sub;
  {
    string t;
    cin >> t;
    sub.init(t);
  }
  int ans = 0;
  for (int l = 0; l <= base.len - sub.len; ++l) {
    ha nh = RollingHash::concat(base.hash(0, l - 1), sub.hash(), sub.len);
    nh = RollingHash::concat(nh, base.hash(sub.len + l, base.len - 1),
                             base.len - sub.len - l);
    if (binary_search(ha_set.begin(), ha_set.end(), nh))
      ans++;
  }
  cout << ans << endl;
  return 0;
}