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

/*input
anagram
grandmother
*/
#include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rep(i, a, b) for (int(i) = (a); (i) < (b); ++(i))
#define sz(x) ((int)(x).size())

using vi = vector<int>;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using vvi = vector<vi>;

namespace std {
template <> struct hash<pair<int, int>> {
  size_t operator()(const pair<int, int> &key) const {
    return hash<int>()(key.first) + hash<int>()(key.second);
  }
};
} // namespace std

inline int mulmod(int a, int b, int p) {
  ll x = a, y = b, z = p;
  return (x * y) % z;
}

constexpr array<int, 2> primes = {1000000007, 1000000023};
array<int, 4001> alphaSize[2];
array<int, 2> val = {0, 0};

struct rollingHash {
  int alpha;
  rollingHash(int alphaSz = 26) {
    alpha = alphaSz;
    rep(i, 0, 2) {
      alphaSize[i][0] = 1;
      rep(j, 1, alpha) alphaSize[i][j] =
          mulmod(alphaSize[i][j - 1], alpha, primes[i]);
    }
  }
  void addC(char &c) {
    int idx = c - 'a';
    rep(i, 0, 2) val[i] = (val[i] + alphaSize[i][idx]) % primes[i];
  }
  void clear() {
    val[0] = 0ll;
    val[1] = 0ll;
  }
};

string a, b;
vector<pii> memo;
rollingHash rk(26);

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> a >> b;
  int lenA = sz(a), lenB = sz(b);
  rep(st, 0, lenA) {
    rk.clear();
    rep(x, st, lenA) {
      rk.addC(a[x]);
      memo.push_back(make_pair(val[0], val[1]));
    }
  }
  sort(all(memo));
  int ans = 0;
  pii needle;
  rep(st, 0, lenB) {
    rk.clear();
    rep(x, st, lenB) {
      rk.addC(b[x]);
      needle = make_pair(val[0], val[1]);
      vector<pii>::iterator it = lower_bound(all(memo), needle);
      if (it != memo.end() && *it == needle)
        ans = max(ans, x - st + 1);
    }
  }
  cout << ans << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rep(i, a, b) for (int(i) = (a); (i) < (b); ++(i))
#define sz(x) ((int)(x).size())

using vi = vector<int>;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using vvi = vector<vi>;

namespace std {
template <> struct hash<pair<int, int>> {
  size_t operator()(const pair<int, int> &key) const {
    return hash<int>()(key.first) + hash<int>()(key.second);
  }
};
} // namespace std

inline int mulmod(int a, int b, int p) {
  ll x = a, y = b, z = p;
  return (x * y) % z;
}

constexpr array<int, 2> primes = {1000000007, 1000000023};

array<int, 4001> alphaSize[2];
array<int, 2> val = {0, 0};

struct rollingHash {
  int alpha;
  rollingHash(int alphaSz = 26) {
    alpha = alphaSz;
    rep(i, 0, 2) {
      alphaSize[i][0] = 1;
      rep(j, 1, alpha) alphaSize[i][j] =
          mulmod(alphaSize[i][j - 1], alpha, primes[i]);
    }
  }
  void addC(char &c) {
    int idx = c - 'a';
    rep(i, 0, 2) val[i] = (val[i] + alphaSize[i][idx]) % primes[i];
  }
  void clear() {
    val[0] = 0ll;
    val[1] = 0ll;
  }
};

string a, b;
unordered_set<pii> memo;
rollingHash rk(26);

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> a >> b;
  int lenA = sz(a), lenB = sz(b);
  rep(st, 0, lenA) {
    rk.clear();
    rep(x, st, lenA) {
      rk.addC(a[x]);
      memo.insert(make_pair(val[0], val[1]));
    }
  }
  int ans = 0;
  rep(st, 0, lenB) {
    rk.clear();
    rep(x, st, lenB) {
      rk.addC(b[x]);
      if (memo.find(make_pair(val[0], val[1])) != memo.end()) {
        ans = max(ans, x - st + 1);
      }
    }
  }
  cout << ans << endl;
  return 0;
}