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

#include <bits/stdc++.h>
using namespace std;
typedef unsigned int ull;
struct RollingHash {
  string S;
  ull B;
  vector<ull> hash, p;
  int len;
  RollingHash() {}
  RollingHash(string S, ull B = 1777771) : S(S), B(B) { init(); };
  void init() {
    len = S.length();
    hash.resize(len + 1);
    p.resize(len + 1);
    hash[0] = 0;
    p[0] = 1;
    for (int i = 0; i < len; i++) {
      hash[i + 1] = hash[i] * B + S[i];
      p[i + 1] = p[i] * B;
    }
  }
  // S[l,r)
  ull find(int l, int r) { return hash[r] - hash[l] * p[r - l]; }
};

signed main() {
  int n, M;
  while (cin >> n >> M, n) {
    string e[n];
    for (int i = 0; i < n; i++)
      cin >> e[i];
    string b, t;
    for (int i = 0; i < M; i++) {
      cin >> t;
      b += t;
    }
    int x = n / 2, y = n - x;
    set<ull> sa;
    set<ull> m[1 << 12];
    set<int> ln[400];
    function<void(int, int, string)> dfs = [&](int d, int c, string s) {
      if (d == x || d == y) {
        RollingHash rh(s);
        ln[s.size()].insert(c);
        m[c].insert(rh.find(0, s.size()));
        sa.insert(rh.find(0, s.size()) >> 4);
        if (d == y)
          return;
      }
      for (int i = 0; i < n; i++) {
        if ((c >> i) & 1)
          continue;
        dfs(d + 1, c + (1 << i), s + e[i]);
      }
    };
    dfs(0, 0, "");
    int len = 0;
    for (int i = 0; i < n; i++)
      len += e[i].size();
    RollingHash rh(b);
    int ans = 0;
    for (int i = 0; i <= (int)b.size() - len; i++) {
      bool flg = 0;
      for (int l = 0; l < 400; l++) {
        if (ln[l].empty())
          continue;
        ull u = rh.find(i, i + l), v = rh.find(i + l, i + len);
        if (!sa.count(u >> 4) || !sa.count(v >> 4))
          continue;
        for (int j : ln[l]) {
          int k = (~j) & ((1 << n) - 1);
          if (m[j].count(u) && m[k].count(v)) {
            flg = 1;
            break;
          }
        }
        if (flg)
          break;
      }
      if (flg)
        ans++;
    }
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned int ull;
struct RollingHash {
  string S;
  ull B;
  vector<ull> hash, p;
  int len;
  RollingHash() {}
  RollingHash(string S, ull B = 1777771) : S(S), B(B) { init(); };
  void init() {
    len = S.length();
    hash.resize(len + 1);
    p.resize(len + 1);
    hash[0] = 0;
    p[0] = 1;
    for (int i = 0; i < len; i++) {
      hash[i + 1] = hash[i] * B + S[i];
      p[i + 1] = p[i] * B;
    }
  }
  // S[l,r)
  ull find(int l, int r) { return hash[r] - hash[l] * p[r - l]; }
};

signed main() {
  int n, M;
  while (cin >> n >> M, n) {
    string e[n];
    for (int i = 0; i < n; i++)
      cin >> e[i];
    string b, t;
    for (int i = 0; i < M; i++) {
      cin >> t;
      b += t;
    }
    int x = n / 2, y = n - x;
    set<ull> sa;
    set<ull> m[1 << 12];
    set<int> ln[400];
    function<void(int, int, string)> dfs = [&](int d, int c, string s) {
      if (d == x || d == y) {
        RollingHash rh(s);
        ln[s.size()].insert(c);
        m[c].insert(rh.find(0, s.size()));
        sa.insert(rh.find(0, s.size()));
        if (d == y)
          return;
      }
      for (int i = 0; i < n; i++) {
        if ((c >> i) & 1)
          continue;
        dfs(d + 1, c + (1 << i), s + e[i]);
      }
    };
    dfs(0, 0, "");
    // cout<<"count:"<<count<<endl;
    int len = 0;
    for (int i = 0; i < n; i++)
      len += e[i].size();
    RollingHash rh(b);
    int ans = 0;
    for (int i = 0; i <= (int)b.size() - len; i++) {
      bool flg = 0;
      for (int l = 0; l < 400; l++) {
        if (ln[l].empty())
          continue;
        ull u = rh.find(i, i + l), v = rh.find(i + l, i + len);
        // if(!sa.count(u)||!sa.count(v)) continue;
        for (int j : ln[l]) {
          int k = (~j) & ((1 << n) - 1);
          if (m[j].count(u) && m[k].count(v)) {
            flg = 1;
            break;
          }
        }
        if (flg)
          break;
      }
      if (flg)
        ans++;
    }
    cout << ans << endl;
  }
  return 0;
}