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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007

struct Trie {
  vector<pair<char, Trie *>> a;
  unsigned short ctr, ctr2;

  Trie() {
    ctr = 0;
    ctr2 = 0;
  }
  void insert(const char *s) {
    if (*s == '\\0') {
      ctr++;
      ctr2++;
      return;
    }
    int k = *s - 'a';
    for (auto p : a) {
      if (k == p._1) {
        p._2->insert(s + 1);
        ctr++;
        return;
      }
    }
    a.pb(make_pair(k, new Trie()));
    a.back()._2->insert(s + 1);
    ctr++;
  }
  int find(const char *s) {
    if (*s == '\\0')
      return ctr;
    int k = *s - 'a';
    for (auto p : a) {
      if (k == p._1)
        return p._2->find(s + 1);
    }
    return 0;
  }

  int find2(const char *s) {
    if (*s == '\\0')
      return ctr2;
    int k = *s - 'a';
    for (auto p : a) {
      if (k == p._1)
        return p._2->find2(s + 1);
    }
    return 0;
  }
  void free() {
    for (auto p : a) {
      p._2->free();
      delete p._2;
    }
    a.clear();
  }
};

int N, Q;
Trie *fwd;
int A[50000];
string S[50000];

int f(string s) { return fwd->find(s.c_str()); }
int f2(string s) { return fwd->find2(s.c_str()); }

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> Q;
  fwd = new Trie;
  rep(i, N) {
    cin >> S[i];
    fwd->insert(S[i].c_str());
  }
  vector<pair<int, string>> qs;
  rep(i, Q) {
    string s;
    cin >> s;
    if (s[0] != '*' && s[s.length() - 1] != '*') {
      int pos = -1;
      rep(i, s.length()) {
        if (s[i] == '?')
          pos = i;
      }
      int sum = 0;
      if (pos != -1) {
        rep(ch, 26) {
          s[pos] = 'a' + ch;
          sum += f2(s);
        }
      } else {
        sum = f2(s);
      }
      A[i] = sum;
      continue;
    }
    bool flip = s[0] == '*';
    if (flip) {
      reverse(all(s));
      qs.pb(make_pair(i, s));
      continue;
    }
    assert(s.back() == '*');
    s.resize((int)s.size() - 1);
    int pos = -1;
    rep(i, s.length()) {
      if (s[i] == '?')
        pos = i;
    }
    int sum = 0;
    if (pos != -1) {
      rep(ch, 26) {
        s[pos] = 'a' + ch;
        sum += f(s);
      }
    } else
      sum = f(s);
    A[i] = sum;
  }
  fwd->free();
  delete fwd;
  fwd = new Trie;
  rep(i, N) {
    reverse(all(S[i]));
    fwd->insert(S[i].c_str());
  }
  for (auto p : qs) {
    int i = p._1;
    string s = p._2;
    assert(s.back() == '*');
    s.resize((int)s.size() - 1);
    int pos = -1;
    rep(i, s.length()) {
      if (s[i] == '?')
        pos = i;
    }
    int sum = 0;
    if (pos != -1) {
      rep(ch, 26) {
        s[pos] = 'a' + ch;
        sum += f(s);
      }
    } else
      sum = f(s);
    A[i] = sum;
  }
  rep(i, Q) cout << A[i] << "\\n";
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919
#define MOD 1000000007

struct Trie {
  vector<pair<char, Trie *>> a;
  unsigned short ctr, ctr2;

  Trie() {
    ctr = 0;
    ctr2 = 0;
  }
  void insert(const char *s) {
    if (*s == '\\0') {
      ctr++;
      ctr2++;
      return;
    }
    int k = *s - 'a';
    for (auto p : a) {
      if (k == p._1) {
        p._2->insert(s + 1);
        ctr++;
        return;
      }
    }
    a.pb(make_pair(k, new Trie()));
    a.back()._2->insert(s + 1);
    ctr++;
  }
  int find(const char *s) {
    if (*s == '\\0')
      return ctr;
    int k = *s - 'a';
    for (auto p : a) {
      if (k == p._1)
        return p._2->find(s + 1);
    }
    return 0;
  }

  int find2(const char *s) {
    if (*s == '\\0')
      return ctr2;
    int k = *s - 'a';
    for (auto p : a) {
      if (k == p._1)
        return p._2->find2(s + 1);
    }
    return 0;
  }
  void free() {
    for (auto p : a)
      p._2->free();
    a.clear();
  }
};

int N, Q;
Trie *fwd;
int A[50000];
string S[50000];

int f(string s) { return fwd->find(s.c_str()); }
int f2(string s) { return fwd->find2(s.c_str()); }

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> Q;
  fwd = new Trie;
  rep(i, N) {
    cin >> S[i];
    fwd->insert(S[i].c_str());
  }
  vector<pair<int, string>> qs;
  rep(i, Q) {
    string s;
    cin >> s;
    if (s[0] != '*' && s[s.length() - 1] != '*') {
      int pos = -1;
      rep(i, s.length()) {
        if (s[i] == '?')
          pos = i;
      }
      int sum = 0;
      if (pos != -1) {
        rep(ch, 26) {
          s[pos] = 'a' + ch;
          sum += f2(s);
        }
      } else {
        sum = f2(s);
      }
      A[i] = sum;
      continue;
    }
    bool flip = s[0] == '*';
    if (flip) {
      reverse(all(s));
      qs.pb(make_pair(i, s));
      continue;
    }
    assert(s.back() == '*');
    s.resize((int)s.size() - 1);
    int pos = -1;
    rep(i, s.length()) {
      if (s[i] == '?')
        pos = i;
    }
    int sum = 0;
    if (pos != -1) {
      rep(ch, 26) {
        s[pos] = 'a' + ch;
        sum += f(s);
      }
    } else
      sum = f(s);
    A[i] = sum;
  }
  fwd->free();
  delete fwd;
  fwd = new Trie;
  rep(i, N) {
    reverse(all(S[i]));
    fwd->insert(S[i].c_str());
  }
  for (auto p : qs) {
    int i = p._1;
    string s = p._2;
    assert(s.back() == '*');
    s.resize((int)s.size() - 1);
    int pos = -1;
    rep(i, s.length()) {
      if (s[i] == '?')
        pos = i;
    }
    int sum = 0;
    if (pos != -1) {
      rep(ch, 26) {
        s[pos] = 'a' + ch;
        sum += f(s);
      }
    } else
      sum = f(s);
    A[i] = sum;
  }
  rep(i, Q) cout << A[i] << "\\n";
  return 0;
}