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

#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll)a); i < ((ll)n); i++)
using namespace std;
typedef int ll;
typedef pair<ll, ll> pll;

class PMA {
  PMA *next[256];
  vector<ll> matched;

  PMA() { REP(i, 0, 256) next[i] = NULL; }

  void build(vector<string> &p) {
    REP(i, 0, 256) next[i] = NULL;
    this->next[0] = this;
    REP(i, 0, p.size()) {
      PMA *now = this;
      REP(j, 0, p[i].length()) {
        if (now->next[p[i][j]] == 0)
          now->next[p[i][j]] = new PMA;
        now = now->next[p[i][j]];
      }
      now->matched.push_back(i);
    }

    queue<PMA *> q;
    REP(i, 1, 256) {
      if (!this->next[i])
        this->next[i] = this;
      else {
        this->next[i]->next[0] = this;
        q.push(this->next[i]);
      }
    }

    while (!q.empty()) {
      PMA *now = q.front();
      q.pop();
      REP(i, 1, 256) if (now->next[i]) {
        PMA *nxt = now->next[0];
        while (!nxt->next[i])
          nxt = nxt->next[0];
        now->next[i]->next[0] = nxt->next[i];
        vector<ll> &m1 = now->next[i]->matched, &m2 = nxt->next[i]->matched;
        REP(j, 0, m2.size())
        if (!binary_search(m1.begin(), m1.end(), m2[j])) m1.push_back(m2[j]);
        sort(m1.begin(), m1.end());
        q.push(now->next[i]);
      }
    }
  }

public:
  PMA(vector<string> &p) { build(p); }

  vector<pll> match(string s) {
    vector<pll> ret;
    PMA *pma = this;
    REP(i, 0, s.length()) {
      while (!pma->next[s[i]])
        pma = pma->next[0];
      pma = pma->next[s[i]];
      for (ll j : pma->matched)
        ret.push_back(pll(i, j));
    }
    return ret;
  }
};

int main(void) {
  string S;
  cin >> S;
  ll N;
  cin >> N;
  vector<string> P(N);
  REP(i, 0, N) cin >> P[i];

  sort(P.begin(), P.end());

  vector<string> Q;
  Q.push_back(P[0]);
  REP(i, 1, P.size()) {
    ll len = min(Q[(ll)Q.size() - 1].size(), P[i].size());
    bool ok = true;
    REP(j, 0, len) ok = ok && (Q[(ll)Q.size() - 1][j] == P[i][j]);
    if (!ok)
      Q.push_back(P[i]);
  }

  PMA pma(Q);
  vector<pll> p = pma.match(S);
  REP(i, 0, p.size()) p[i].second = p[i].first + 1 - Q[p[i].second].length();
  sort(p.begin(), p.end());

  ll ans = 0, t = -1;
  REP(i, 0, p.size()) {
    if (t < p[i].second) {
      ans++;
      t = p[i].first;
    }
  }

  cout << ans << endl;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll)a); i < ((ll)n); i++)
using namespace std;
typedef int ll;
typedef pair<ll, ll> pll;

class PMA {
  PMA *next[256];
  vector<ll> matched;

  PMA() { REP(i, 0, 256) next[i] = NULL; }

  void build(vector<string> &p) {
    REP(i, 0, 256) next[i] = NULL;
    this->next[0] = this;
    REP(i, 0, p.size()) {
      PMA *now = this;
      REP(j, 0, p[i].length()) {
        if (now->next[p[i][j]] == 0)
          now->next[p[i][j]] = new PMA;
        now = now->next[p[i][j]];
      }
      now->matched.push_back(i);
    }

    queue<PMA *> q;
    REP(i, 1, 256) {
      if (!this->next[i])
        this->next[i] = this;
      else {
        this->next[i]->next[0] = this;
        q.push(this->next[i]);
      }
    }

    while (!q.empty()) {
      PMA *now = q.front();
      q.pop();
      REP(i, 1, 256) if (now->next[i]) {
        PMA *nxt = now->next[0];
        while (!nxt->next[i])
          nxt = nxt->next[0];
        now->next[i]->next[0] = nxt->next[i];
        vector<ll> &m1 = now->next[i]->matched, &m2 = nxt->next[i]->matched;
        REP(j, 0, m2.size())
        if (!binary_search(m1.begin(), m1.end(), m2[j])) m1.push_back(m2[j]);
        sort(m1.begin(), m1.end());
        q.push(now->next[i]);
      }
    }
  }

public:
  PMA(vector<string> &p) { build(p); }

  vector<pll> match(string s) {
    vector<pll> ret;
    PMA *pma = this;
    REP(i, 0, s.length()) {
      while (!pma->next[s[i]])
        pma = pma->next[0];
      pma = pma->next[s[i]];
      for (ll j : pma->matched)
        ret.push_back(pll(i, j));
    }
    return ret;
  }
};

int main(void) {
  string S;
  cin >> S;
  ll N;
  cin >> N;
  vector<string> P(N);
  REP(i, 0, N) cin >> P[i];

  sort(P.begin(), P.end());
  P.erase(unique(P.begin(), P.end()), P.end());

  PMA pma(P);
  vector<pll> p = pma.match(S);
  REP(i, 0, p.size()) p[i].second = p[i].first + 1 - P[p[i].second].length();
  sort(p.begin(), p.end());

  ll ans = 0, t = -1;
  REP(i, 0, p.size()) {
    if (t < p[i].second) {
      ans++;
      t = p[i].first;
    }
  }

  cout << ans << endl;
}