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

#include <algorithm>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

#define ull unsigned long long
#define pp pair<ull, ull>
const ull MAXN = 4233;
#define vecu vector<ull>
#define vevi vector<int>
#define vecp vector<pp>
const ull HASH_P1 = 4003;
const ull HASH_P2 = 4007;
const ull HASH_MOD1 = 1000247;
const ull HASH_MOD2 = 1000000037;
#define hash1(x, b) (((ull)x * HASH_P1 + b) % HASH_MOD1)
#define hash2(x, b) (((ull)x * HASH_P2 + b) % HASH_MOD2)
#define next_hash(tmp, b) (make_pair(hash1(tmp.first, b), hash2(tmp.second, b)))
#define add_hash(tmp, b)                                                       \\
  (make_pair((tmp.first + hash_hex[idx(b)].first) % HASH_MOD1,                 \\
             (tmp.second + hash_hex[idx(b)].second) % HASH_MOD2))
#define sub_hash(tmpa, tmpb)                                                   \\
  (make_pair((tmpa.first + HASH_MOD1 - tmpb.first) % HASH_MOD1,                \\
             (tmpa.second + HASH_MOD2 - tmpb.second) % HASH_MOD2))
#define idx(x) (x - 'a')

char str1[MAXN];
char str2[MAXN];
int str1_len, str2_len;
pp hash_hex[MAXN];
pp str1_hash[MAXN];
pp str2_hash[MAXN];

vecu hash_table[HASH_MOD1];
inline bool find_key(ull idx, ull key) {
  int len = hash_table[idx].size();
  for (int i = 0; i < len; ++i) {
    if (hash_table[idx][i] == key)
      return true;
  }
  return false;
}
inline void hash_insert(ull idx, ull key) { hash_table[idx].push_back(key); }
inline void hash_clear(ull idx) { hash_table[idx].clear(); }

inline bool check(int length) {
  hash_insert(str1_hash[length - 1].first, str1_hash[length - 1].second);
  for (int i = length; i < str1_len; ++i) {
    pp tmp = sub_hash(str1_hash[i], str1_hash[i - length]);
    hash_insert(tmp.first, tmp.second);
  }
  if (find_key(str2_hash[length - 1].first, str2_hash[length - 1].second))
    return true;
  for (int i = length; i < str2_len; ++i) {
    pp tmp = sub_hash(str2_hash[i], str2_hash[i - length]);
    // hash_insert(tmp.first,tmp.second);
    if (find_key(tmp.first, tmp.second))
      return true;
  }

  hash_clear(str1_hash[length - 1].first);
  for (int i = length; i < str1_len; ++i) {
    pp tmp = sub_hash(str1_hash[i], str1_hash[i - length]);
    hash_clear(tmp.first);
  }

  return false;
}

void init() {

  str1_len = strlen(str1);
  str2_len = strlen(str2);
  str1_hash[0] = hash_hex[idx(str1[0])];
  str2_hash[0] = hash_hex[idx(str2[0])];

  for (int i = 1; i < str1_len; ++i)
    str1_hash[i] = add_hash(str1_hash[i - 1], str1[i]);
  for (int i = 1; i < str2_len; ++i)
    str2_hash[i] = add_hash(str2_hash[i - 1], str2[i]);

  int limit = min(str1_len, str2_len);
  int ans = 0;
  for (int i = limit; i; i--) {
    if (check(i)) {
      ans = i;
      break;
    }
  }
  cout << ans << "\\n";
}

int main() {

  hash_hex[0] = make_pair(1, 1);
  for (int i = 1; i < 233; ++i)
    hash_hex[i] = next_hash(hash_hex[i - 1], 0);
  // while(gets(str1)&&gets(str2))init();
  while (~scanf("%s %s", str1, str2))
    init();
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const ll MOD = 1000000007;

int main() {
  string s1, s2;
  cin >> s1 >> s2;

  if (s1.size() > s2.size()) {
    swap(s1, s2);
  }

  const ll base = 9973;
  vector<ll> base_pow(26);
  base_pow[0] = 1;
  for (int i = 1; i < 26; i++) {
    base_pow[i] = (base_pow[i - 1] * base) % MOD;
  }

  unordered_map<int, vector<P>> viewed;
  for (int i = 0; i < s1.size(); i++) {
    ll hash = 0;
    for (int j = i; j < s1.size(); j++) {
      hash += base_pow[int(s1[j] - 'a')];
      hash %= MOD;
      viewed[hash].emplace_back(j - i + 1, i);
    }
  }

  vector<tuple<int, int, int>> ans_cand;
  for (int i = 0; i < s2.size(); i++) {
    ll hash = 0;
    for (int j = i; j < s2.size(); j++) {
      hash += base_pow[int(s2[j] - 'a')];
      hash %= MOD;
      auto it = viewed.find(hash);
      if (it != viewed.end()) {
        for (P &p : it->second) {
          ans_cand.emplace_back(p.first, p.second, i);
        }
      }
    }
  }

  int ans = 0;
  sort(ans_cand.begin(), ans_cand.end());
  for (int j = 0; j < ans_cand.size(); j++) {
    tuple<int, int, int> &cand = ans_cand[int(ans_cand.size()) - j - 1];
    vector<int> cnt(26, 0);
    int K = get<0>(cand);
    int b1 = get<1>(cand), b2 = get<2>(cand);
    for (int k = 0; k < K; k++) {
      cnt[int(s1[b1 + k] - 'a')]++;
      cnt[int(s2[b2 + k] - 'a')]--;
    }
    bool ok = true;
    for (int i = 0; i < 26; i++) {
      if (cnt[i] != 0) {
        ok = false;
        break;
      }
    }
    if (ok) {
      ans = K;
      break;
    }
  }

  cout << ans << endl;

  return 0;
}