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

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<PII> VP;
typedef vector<ll> VL;
typedef vector<VL> VVL;

string s1, s2;
VVI cnt1, cnt2;

void fillcnt(VVI &cnt, string &s) {
  cnt = VVI(s.size(), VI(26, 0));
  cnt[0][s[0] - 'a'] = 1;
  for (int i = 1; i < s.size(); ++i) {
    cnt[i] = cnt[i - 1];
    cnt[i][s[i] - 'a']++;
  }
}

bool equal_cnt(int i1, int j1, int i2, int j2) {
  for (int k = 0; k < 26; ++k) {
    int d1 = cnt1[j1][k] - (i1 == 0 ? 0 : cnt1[i1 - 1][k]);
    int d2 = cnt2[j2][k] - (i2 == 0 ? 0 : cnt2[i2 - 1][k]);
    if (d1 != d2)
      return false;
  }
  return true;
}

VI vals = {1,   3,   5,   11,  13,  17,  31,  42,  56,  67,  79,  86,  93,
           156, 249, 372, 271, 346, 449, 879, 764, 913, 637, 267, 435, 289};
int main() {
  ios::sync_with_stdio(false);
  cin >> s1 >> s2;
  fillcnt(cnt1, s1);
  fillcnt(cnt2, s2);
  /*unordered_map<ll, VP> ht;
  for (int i = 0; i < s1.size(); ++i) {
          ll hs = 0;
          for (int j = i; j < s1.size(); ++j) {
                  hs += vals[s1[j]-'a'];
                  ht[gethash(hs, j-i+1)].emplace_back(i, j);
          }
  }
  int sol = 0;
  for (int i = 0; i < s2.size(); ++i) {
          ll hs = 0;
          for (int j = i; j < s2.size(); ++j) {
                  hs += vals[s2[j]-'a'];
                  if (ht.count(gethash(hs, j-i+1)) == 0) continue;
                  for (auto& pr : ht[gethash(hs, j-i+1)]) {
                          if (equal_cnt(pr.first, pr.second, i, j))
                                  sol = max(sol, j-i+1);
                  }
          }
  }*/
  int sol = 0;
  for (int jmp = min(s1.size(), s2.size()) - 1; jmp >= 0; --jmp) {
    unordered_map<ll, VI> ht;
    ll hs = 0;
    for (int i = 0; i < jmp; ++i)
      hs += vals[s1[i] - 'a'];
    for (int i = 0; i + jmp < s1.size(); ++i) {
      hs += vals[s1[i + jmp] - 'a'];
      ht[hs].push_back(i);
      hs -= vals[s1[i] - 'a'];
    }
    hs = 0;
    for (int i = 0; i < jmp && i < s2.size(); ++i)
      hs += vals[s2[i] - 'a'];
    for (int i = 0; i + jmp < s2.size(); ++i) {
      hs += vals[s2[i + jmp] - 'a'];
      if (ht.count(hs) != 0) {
        for (int i1 : ht[hs]) {
          if (equal_cnt(i1, i1 + jmp, i, i + jmp))
            sol = max(sol, jmp + 1);
        }
      }
      hs -= vals[s2[i] - 'a'];
    }
    if (sol > 0)
      break;
  }
  cout << sol << '\\n';
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<PII> VP;
typedef vector<ll> VL;
typedef vector<VL> VVL;

string s1, s2;
VVI cnt1, cnt2;

void fillcnt(VVI &cnt, string &s) {
  cnt = VVI(s.size(), VI(26, 0));
  cnt[0][s[0] - 'a'] = 1;
  for (int i = 1; i < s.size(); ++i) {
    cnt[i] = cnt[i - 1];
    cnt[i][s[i] - 'a']++;
  }
}
const ll hc = 1e11;
ll gethash(ll sum, ll len) { return sum + len * hc; }

bool equal_cnt(int i1, int j1, int i2, int j2) {
  for (int k = 0; k < 26; ++k) {
    int d1 = cnt1[j1][k] - (i1 == 0 ? 0 : cnt1[i1 - 1][k]);
    int d2 = cnt2[j2][k] - (i2 == 0 ? 0 : cnt2[i2 - 1][k]);
    if (d1 != d2)
      return false;
  }
  return true;
}

VI vals = {1,   3,   5,   11,  13,  17,  31,  42,  56,  67,  79,  86,  93,
           156, 249, 372, 271, 346, 449, 879, 764, 913, 637, 267, 435, 289};
int main() {
  ios::sync_with_stdio(false);
  cin >> s1 >> s2;
  fillcnt(cnt1, s1);
  fillcnt(cnt2, s2);
  unordered_map<ll, VP> ht;
  for (int i = 0; i < s1.size(); ++i) {
    ll hs = 0;
    for (int j = i; j < s1.size(); ++j) {
      hs += vals[s1[j] - 'a'];
      ht[gethash(hs, j - i + 1)].emplace_back(i, j);
    }
  }
  int sol = 0;
  for (int i = 0; i < s2.size(); ++i) {
    ll hs = 0;
    for (int j = i; j < s2.size(); ++j) {
      hs += vals[s2[j] - 'a'];
      if (ht.count(gethash(hs, j - i + 1)) == 0)
        continue;
      for (auto &pr : ht[gethash(hs, j - i + 1)]) {
        if (equal_cnt(pr.first, pr.second, i, j))
          sol = max(sol, j - i + 1);
      }
    }
  }
  cout << sol << '\\n';
}