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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
// clang-format off
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\\n";}()
template<class T> inline void dump2D(T &d, size_t sizey, size_t sizex) {
  for(size_t i = 0; i < sizey; i++) { for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << " "; DEBUG_OUT << endl; }
}
#else
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (42)
#define dump2D(...) (42)
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
// clang-format on
// }}}

// never fail to call build() !!
// constructor()
// add(string)
// match(string) : [left, right], vec<tuple<int left, int right, int key>> in
// right-order
/// --- AhoCorasick Library {{{ ///

const int inf = 1e9;
struct AhoCorasick {
  struct Trie {
    unordered_map<char, Trie *> child;
    Trie *failure = nullptr;
    int shortestWord = inf;
    Trie *add(char c) {
      if (child.count(c)) {
        return child[c];
      } else {
        return child[c] = new Trie;
      }
    }
    Trie *go(char c) {
      if (child.count(c)) {
        return child[c];
      } else {
        if (failure == nullptr) {
          return this;
        } else {
          return failure->go(c);
        }
      }
    }
  };
  Trie *top = new Trie;
  vector<string> dict;
  void add(string word) {
    Trie *now = top;
    for (size_t i = 0; i < word.size(); i++) {
      now = now->add(word[i]);
    }
    now->shortestWord = min(now->shortestWord, (int)word.size());
  }
  void build() {
    queue<Trie *> q;
    q.emplace(top);
    while (q.size()) {
      Trie *now = q.front();
      q.pop();
      for (pair<char, Trie *> ch : now->child) {
        q.emplace(ch.second);
        Trie *failure = ch.second->failure =
            now == top ? top : now->failure->go(ch.first);
        /// only from failure!!
        // vector< int >& words = ch.second->words;
        ch.second->shortestWord =
            min(ch.second->shortestWord, failure->shortestWord);
        // words.insert(end(words), begin(failure->words), end(failure->words));
      }
    }
  }
  vector<tuple<int, int, int>> match(string s) {
    Trie *now = top;
    vector<tuple<int, int, int>> res;
    for (size_t i = 0; i < s.size(); i++) {
      now = now->go(s[i]);
      if (now->shortestWord != inf)
        res.emplace_back(i - now->shortestWord + 1, i, 0);
    }
    return res;
  }
};

/// }}}--- ///

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  string s;
  cin >> s;
  int m;
  cin >> m;
  vector<string> t(m);
  AhoCorasick ecasd;
  for (int i = 0; i < m; i++) {
    cin >> t[i];
    ecasd.add(t[i]);
  }
  ecasd.build();
  auto v = ecasd.match(s);
  int last = -1;
  ll ans = 0;
  dump(v);
  // あとは区間スケジューリング問題
  for (int i = 0; i < v.size(); i++) {
    int le, ri, key;
    tie(le, ri, key) = v[i];
    if (last >= le)
      continue;
    last = ri;
    ans++;
  }
  cout << ans << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
// clang-format off
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\\n";}()
template<class T> inline void dump2D(T &d, size_t sizey, size_t sizex) {
  for(size_t i = 0; i < sizey; i++) { for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << " "; DEBUG_OUT << endl; }
}
#else
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (42)
#define dump2D(...) (42)
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
// clang-format on
// }}}

// never fail to call build() !!
// constructor()
// add(string)
// match(string) : [left, right], vec<tuple<int left, int right, int key>> in
// right-order
/// --- AhoCorasick Library {{{ ///

struct AhoCorasick {
  struct Trie {
    unordered_map<char, Trie *> child;
    Trie *failure = nullptr;
    vector<int> words;
    Trie *add(char c) {
      if (child.count(c)) {
        return child[c];
      } else {
        return child[c] = new Trie;
      }
    }
    Trie *go(char c) {
      if (child.count(c)) {
        return child[c];
      } else {
        if (failure == nullptr) {
          return this;
        } else {
          return failure->go(c);
        }
      }
    }
  };
  Trie *top = new Trie;
  vector<string> dict;
  void add(string word) {
    Trie *now = top;
    for (size_t i = 0; i < word.size(); i++) {
      now = now->add(word[i]);
    }
    now->words.emplace_back(dict.size());
    dict.emplace_back(word);
  }
  void build() {
    queue<Trie *> q;
    q.emplace(top);
    while (q.size()) {
      Trie *now = q.front();
      q.pop();
      for (pair<char, Trie *> ch : now->child) {
        q.emplace(ch.second);
        Trie *failure = ch.second->failure =
            now == top ? top : now->failure->go(ch.first);
        /// only from failure!!
        vector<int> &words = ch.second->words;
        words.insert(end(words), begin(failure->words), end(failure->words));
      }
    }
  }
  vector<tuple<int, int, int>> match(string s) {
    Trie *now = top;
    vector<tuple<int, int, int>> res;
    for (size_t i = 0; i < s.size(); i++) {
      now = now->go(s[i]);
      for (int word : now->words) {
        res.emplace_back(i - dict[word].size() + 1, i, word);
      }
    }
    return res;
  }
};

/// }}}--- ///

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  string s;
  cin >> s;
  int m;
  cin >> m;
  vector<string> t(m);
  AhoCorasick ecasd;
  for (int i = 0; i < m; i++) {
    cin >> t[i];
    ecasd.add(t[i]);
  }
  ecasd.build();
  auto v = ecasd.match(s);
  int last = -1;
  ll ans = 0;
  dump(v);
  for (int i = 0; i < v.size(); i++) {
    int le, ri, key;
    tie(le, ri, key) = v[i];
    if (last >= le)
      continue;
    last = ri;
    ans++;
  }
  cout << ans << endl;
  return 0;
}