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

#include <bits/stdc++.h>
using namespace std;
const int N = 4010;
const int MAX_N = 3000009;
#define ll long long
int a[30], b[30];
struct Node {
  int fi, sc, tr;
};
vector<Node> mp[MAX_N];
const int mod1 = 10000007;
const int mod2 = 38424785;
const int mod3 = MAX_N;
const int pp1 = 324;
const int pp2 = 94589;
char s1[N], s2[N];
int len1, len2;
ll p1[30], p2[30];
int main() {
  p1[0] = p2[0] = 1;
  for (int i = 1; i <= 26; i++)
    p1[i] = p1[i - 1] * pp1 % mod1;
  for (int i = 1; i <= 26; i++)
    p2[i] = p2[i - 1] * pp2 % mod2;
  cin >> s1 >> s2;
  len1 = strlen(s1);
  len2 = strlen(s2);
  ll h1, h2;
  int res = 0;
  for (int i = 0; i < len1; i++) {
    memset(a, 0, sizeof(a));
    for (int j = i; j < len1; j++) {
      a[s1[j] - 'a']++;
      h1 = h2 = 0;
      for (int k = 0; k < 26; k++)
        if (a[k]) {
          h1 += a[k] * p1[k];
          h1 %= mod1;
          h2 += a[k] * p2[k];
          h2 %= mod2;
        }
      ll H = (h1 << 15) ^ h2;
      H %= mod3;
      // if (i == 0 && j == len1 - 1)
      //	printf("1H % lld % lld %lld \\n", h1, h2, H);
      mp[H].push_back((Node){(int)h1, (int)h2, j - i});
    }
  }
  for (int i = 0; i < len2; i++) {
    memset(b, 0, sizeof(b));
    for (int j = i; j < len2; j++) {
      b[s2[j] - 'a']++;
      h1 = h2 = 0;
      for (int k = 0; k < 26; k++)
        if (b[k]) {
          h1 += b[k] * p1[k];
          h1 %= mod1;
          h2 += b[k] * p2[k];
          h2 %= mod2;
        }
      ll H = (h1 << 15) ^ h2;
      H %= mod3;
      // printf("%d %d----\\n", i, j);
      // if (i == 0 && j == len1 - 1)
      //	printf("2H % lld % lld %lld \\n", h1, h2, H);
      for (int k = 0; k < mp[H].size(); k++)
        if (mp[H][k].fi == h1 && mp[H][k].sc == h2 && mp[H][k].tr == j - i) {
          res = max(res, j - i + 1);
        }
    }
  }
  cout << res << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> PII;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int K = 1e6 + 7;
const int mod = 1e9 + 7;

char sa[K], sb[K];
char tmp[200];
int cnt[200];

#define MAXNUM 13
// 定?字典???体
typedef struct Trie {
  bool flag; // 从根到此是否?一个??
  Trie *next[MAXNUM];
} Trie;
// 声明一个根
Trie *root;
// 初始化?根
void init() {
  root = (Trie *)malloc(sizeof(Trie));
  root->flag = false;
  for (int i = 0; i < MAXNUM; i++)
    root->next[i] = NULL;
}
//??字典?的插入??操作
void insert(char *word) {
  Trie *tem = root;
  while (*word != '\\0') {
    if (tem->next[*word - 'a'] == NULL) {
      Trie *cur = (Trie *)malloc(sizeof(Trie));
      for (int i = 0; i < MAXNUM; i++)
        cur->next[i] = NULL;
      cur->flag = false;
      tem->next[*word - 'a'] = cur;
    }
    tem = tem->next[*word - 'a'];
    word++;
  }
  tem->flag = true;
}
//??一个??的操作
bool search(char *word) {
  Trie *tem = root;
  for (int i = 0; word[i] != '\\0'; i++) {
    if (tem == NULL || tem->next[word[i] - 'a'] == NULL)
      return false;
    tem = tem->next[word[i] - 'a'];
  }
  return tem->flag;
}
int main(void) {
  scanf("%s%s", sa + 1, sb + 1);
  int la = strlen(sa + 1), lb = strlen(sb + 1);
  init();
  tmp[26 * 4] = '\\0';
  for (int i = 1; i <= lb; i++) {
    for (int i = 0; i < 26 * 4; i++)
      tmp[i] = 'a' + 10;
    for (int i = 'a'; i <= 'z'; i++)
      cnt[i] = 0;
    for (int j = i; j <= lb; j++) {
      int x = ++cnt[sb[j]];
      int st = (sb[j] - 'a') * 4, a = x / 10000, b = (x / 100) % 10,
          c = (x / 10) % 10, d = x % 10;
      tmp[st] = a + 'a', tmp[st + 1] = b + 'a', tmp[st + 2] = c + 'a',
      tmp[st + 3] = d + 'a';
      insert(tmp);
    }
  }
  int ans = 0;
  for (int i = 1; i <= la; i++) {
    for (int i = 0; i < 26 * 4; i++)
      tmp[i] = 'a' + 10;
    for (int i = 'a'; i <= 'z'; i++)
      cnt[i] = 0;
    for (int j = i; j <= la; j++) {
      int x = ++cnt[sa[j]];
      int st = (sa[j] - 'a') * 4, a = x / 10000, b = (x / 100) % 10,
          c = (x / 10) % 10, d = x % 10;
      tmp[st] = a + 'a', tmp[st + 1] = b + 'a', tmp[st + 2] = c + 'a',
      tmp[st + 3] = d + 'a';
      if (search(tmp))
        ans = max(ans, j - i + 1);
    }
  }
  printf("%d\\n", ans);
  return 0;
}