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

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#define llint unsigned long long
#define h 1000000007

using namespace std;

string s, t;
int nums[4005][26], numt[4005][26];
llint Hash[26][4005];
llint hbeki[4005];
vector<llint> vect;

int main(void) {
  cin >> s >> t;
  int lens = s.size(), lent = t.size();
  s = "#" + s;
  t = "#" + t;

  hbeki[0] = 1;
  for (int i = 1; i < 4005; i++) {
    hbeki[i] = hbeki[i - 1] * h;
  }

  for (int i = 1; i <= lens; i++) {
    for (int j = 0; j < 26; j++)
      nums[i][j] = nums[i - 1][j];
    nums[i][s[i] - 'a']++;
  }
  for (int i = 1; i <= lent; i++) {
    for (int j = 0; j < 26; j++)
      numt[i][j] = numt[i - 1][j];
    numt[i][t[i] - 'a']++;
  }

  for (int i = 0; i < 26; i++) {
    llint x = 0;
    for (int j = 0; j < 4005; j++) {
      x *= h;
      x += i + 'a';
      Hash[i][j] = x;
    }
  }

  for (int l = 1; l <= lent; l++) {
    for (int r = 1; r <= lent; r++) {
      if (l > r)
        continue;
      llint sum = 0;
      for (int i = 0; i < 26; i++) {
        int n = numt[r][i] - numt[l - 1][i];
        sum += Hash[i][n];
        sum *= hbeki[n];
      }
      vect.push_back(sum);
    }
  }
  sort(vect.begin(), vect.end());

  llint ans = 0;
  for (llint l = 1; l <= lens; l++) {
    for (llint r = 1; r <= lens; r++) {
      if (l > r)
        continue;
      llint sum = 0;
      for (int i = 0; i < 26; i++) {
        int n = nums[r][i] - nums[l - 1][i];
        sum += Hash[i][n];
        sum *= hbeki[n];
      }
      if (sum == *lower_bound(vect.begin(), vect.end(), sum)) {
        ans = max(ans, r - l + 1);
      }
    }
  }

  cout << ans << endl;

  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct combi {
  short num[26];
  combi(){};
  combi(int a[26]) {
    for (int i = 0; i < 26; i++)
      num[i] = a[i];
  }
  bool operator<(combi ope) {
    for (int i = 0; i < 26; i++) {
      if (num[i] == ope.num[i])
        continue;
      return num[i] < ope.num[i];
    }
    return false;
  }
  bool operator==(combi ope) {
    for (int i = 0; i < 26; i++)
      if (num[i] != ope.num[i])
        return false;
    return true;
  }
};

string S1, S2;
vector<combi> vec;
int cnt1[4005][26], cnt2[4005][26];

void count(string S, int cnt[4005][26]) {
  int now[26];
  for (int i = 0; i < 26; i++)
    now[i] = 0;

  for (int i = 1; i <= S.size(); i++) {
    now[S[i - 1] - 'a']++;
    for (int j = 0; j < 26; j++)
      cnt[i][j] = now[j];
  }
}

int main(void) {
  cin >> S1 >> S2;

  count(S1, cnt1);
  count(S2, cnt2);

  int dif[26];
  for (int i = 1; i <= S1.size(); i++) {
    for (int j = 1; j <= S1.size(); j++) {
      if (i > j)
        continue;
      for (int k = 0; k < 26; k++)
        dif[k] = cnt1[j][k] - cnt1[i - 1][k];
      vec.push_back(combi(dif));
    }
  }
  sort(vec.begin(), vec.end());

  int ans = 0;
  vector<combi>::iterator p;

  int sum;
  combi dif2;
  for (int i = 1; i <= S2.size(); i++) {
    for (int j = 1; j <= S2.size(); j++) {
      if (i > j)
        continue;
      for (int k = 0; k < 26; k++)
        dif2.num[k] = cnt2[j][k] - cnt2[i - 1][k];
      p = lower_bound(vec.begin(), vec.end(), dif2);
      if (p != vec.end() && *p == dif2) {
        sum = 0;
        for (int k = 0; k < 26; k++)
          sum += dif2.num[k];
        ans = max(ans, sum);
      }
    }
  }

  cout << ans << endl;
  return 0;
}