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

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

int n, m;
string pre[50000], suf[50000];

int count(string s, bool muki) {
  if (s[s.length() - 1] == '*') {
    s = s.substr(0, s.length() - 1);
    string t = s;
    t[t.length() - 1]++;
    if (!muki)
      return lower_bound(pre, pre + n, t) - lower_bound(pre, pre + n, s);
    else
      return lower_bound(suf, suf + n, t) - lower_bound(suf, suf + n, s);
  } else {
    if (!muki)
      return upper_bound(pre, pre + n, s) - lower_bound(pre, pre + n, s);
    else
      return upper_bound(suf, suf + n, s) - lower_bound(suf, suf + n, s);
  }
}

int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> pre[i];
    suf[i] = pre[i];
    reverse(suf[i].begin(), suf[i].end());
  }
  sort(pre, pre + n);
  sort(suf, suf + n);
  for (int i = 0; i < m; i++) {
    int ind = -1;
    string s;
    cin >> s;
    for (int j = 0; j < s.length(); j++) {
      if (s[j] == '?')
        ind = j;
    }
    if (s[s.length() - 1] == '*') {
      if (ind == -1)
        cout << count(s, false) << endl;
      else {
        int ans = 0;
        for (int j = 0; j < 26; j++) {
          s[ind] = 'a' + j;
          ans += count(s, false);
        }
        cout << ans << endl;
      }
    } else if (s[0] == '*') {
      reverse(s.begin(), s.end());
      if (ind == -1)
        cout << count(s, true) << endl;
      else {
        for (int j = 0; j < s.length(); j++) {
          if (s[j] == '?')
            ind = j;
        }
        int ans = 0;
        for (int j = 0; j < 26; j++) {
          s[ind] = 'a' + j;
          ans += count(s, true);
        }
        cout << ans << endl;
      }
    } else {
      if (ind == -1)
        cout << count(s, false) << endl;
      else {
        int ans = 0;
        for (int j = 0; j < 26; j++) {
          s[ind] = 'a' + j;
          ans += count(s, false);
        }
        cout << ans << endl;
      }
    }
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
using namespace std;

struct Trie {
  int value, end;
  Trie *next[26];
  Trie() {
    fill(next, next + 26, (Trie *)0);
    value = 0;
    end = 0;
  }
};

struct state {
  char *t;
  Trie *r;
};

void *push(char *t, Trie *r) {
  for (int i = 0; t[i]; i++) {
    char c = t[i] - 'a';
    if (!r->next[c])
      r->next[c] = new Trie;
    r->next[c]->value++;
    if (!t[i + 1])
      r->next[c]->end++;
    r = r->next[c];
  }
}

int bfs(char *a, Trie *b) {
  int ans = 0;
  queue<state> que;
  que.push({a, b});
  while (!que.empty()) {
    state s = que.front();
    que.pop();
    char *t = s.t;
    Trie *r = s.r;
    if (t[0] == '*')
      ans += r->value;
    else if (t[0] == '\\0')
      ans += r->end;
    else if (t[0] == '?') {
      for (int i = 0; i < 26; i++) {
        if (r->next[i])
          que.push({t + 1, r->next[i]});
      }
    } else {
      char c = t[0] - 'a';
      if (!r->next[c])
        continue;
      que.push({t + 1, r->next[c]});
    }
  }
  return ans;
}

int dfs(char *t, Trie *r) {
  if (t[0] == '*')
    return r->value;
  if (t[0] == '\\0')
    return r->end;
  if (t[0] == '?') {
    int ans = 0;
    for (int i = 0; i < 26; i++) {
      if (r->next[i])
        ans += dfs(t + 1, r->next[i]);
    }
    return ans;
  }
  char c = t[0] - 'a';
  if (!r->next[c])
    return 0;
  return dfs(t + 1, r->next[c]);
}

int main() {
  Trie *pre, *suf;
  pre = new Trie;
  suf = new Trie;
  int n, m;
  char *cstr = new char[201];
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    strcpy(cstr, s.c_str());
    push(cstr, pre);
    reverse(s.begin(), s.end());
    strcpy(cstr, s.c_str());
    push(cstr, suf);
  }
  for (int i = 0; i < m; i++) {
    string s;
    cin >> s;
    if (s[s.length() - 1] == '*') {
      strcpy(cstr, s.c_str());
      cout << bfs(cstr, pre) << endl;
    } else if (s[0] == '*') {
      reverse(s.begin(), s.end());
      strcpy(cstr, s.c_str());
      cout << bfs(cstr, suf) << endl;
    } else {
      strcpy(cstr, s.c_str());
      cout << bfs(cstr, pre) << endl;
    }
  }
  return 0;
}