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

#include <bits/stdc++.h>
using namespace std;
#define reps(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) reps(i, 0, n)
#define Rreps(i, n, e) for (int i = n - 1; i >= e; --i)
#define Rrep(i, n) Rreps(i, n, 0)
#define ALL(a) a.begin(), a.end()
#define fi first
#define se second
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;

ll N, M, H, W, Q, K, A, B;
string S;
// const ll MOD = 998244353;
const ll MOD = (1e+9) + 7;
typedef pair<ll, ll> P;
const ll INF = (1LL << 58);

struct trie {
  mat G, num;
  vec dflt, dflt_num;
  trie()
      : G(1, vec(26, -1)), num(1, vec(26, 0)), dflt(26, -1), dflt_num(26, 0) {}
  void append(string s) {
    int now = 0;
    int last_id = *s.rbegin() - 'a';
    s.pop_back();
    for (char c : s) {
      int id = c - 'a';
      if (G[now][id] == -1) {
        G[now][id] = G.size();
        now = G.size();
        G.push_back(dflt);
        num.push_back(dflt_num);
      } else {
        now = G[now][id];
      }
    }
    ++num[now][last_id];
  }
  int ans(string s) {
    int now = 0, res = 0, last_id = *s.rbegin() - 'a';
    vec place(26);
    rep(i, 26) {
      place[i] = s.rend() - find(s.rbegin(), s.rend(), char('a' + i));
    }
    s.pop_back();
    rep(i, s.size()) {
      rep(j, 26) {
        if (place[j] >= i + 1)
          res += num[now][j];
      }
      now = G[now][s[i] - 'a'];
    }
    rep(j, 26) {
      if (place[j] >= s.size() + 1)
        res += num[now][j];
    }
    return res;
  }
};

int main() {
  cin >> N;
  vector<string> s(N);
  trie data;
  rep(i, N) {
    cin >> s[i];
    reverse(ALL(s[i]));
    data.append(s[i]);
  }
  ll res = 0;
  rep(i, N) { res += data.ans(s[i]) - 1; }
  cout << res << endl;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define reps(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) reps(i, 0, n)
#define Rreps(i, n, e) for (int i = n - 1; i >= e; --i)
#define Rrep(i, n) Rreps(i, n, 0)
#define ALL(a) a.begin(), a.end()
#define fi first
#define se second
typedef int ll;
typedef vector<ll> vec;
typedef vector<vec> mat;

ll N, M, H, W, Q, K, A, B;
string S;
// const ll MOD = 998244353;
const ll MOD = (1e+9) + 7;
typedef pair<ll, ll> P;
const ll INF = (1LL << 58);

struct trie {
  int Gsize;
  vector<P> G[1000005];
  vec num;
  trie() : Gsize(1), num(1, 0) {}
  void append(string &s) {
    int now = 0;
    ++num[now];
    for (char c : s) {
      int id = c - 'a';
      bool flag = false;
      for (P p : G[now]) {
        if (p.fi == id) {
          now = p.se;
          ++num[now];
          flag = true;
          break;
        }
      }
      if (!flag) {
        G[now].emplace_back(id, Gsize);
        now = Gsize++;
        num.push_back(1);
      }
    }
  }
  int ans(string &s) {
    int now = 0;
    for (char c : s) {
      int id = c - 'a';
      for (P p : G[now]) {
        if (p.fi == id) {
          now = p.se;
          break;
        }
      }
    }
    return num[now];
  }
};

int main() {
  cin >> N;
  vector<string> s(N);
  vector<trie> data(26);
  rep(i, N) {
    cin >> s[i];
    reverse(ALL(s[i]));
    S = s[i];
    vector<bool> exist(26, false);
    Rrep(j, s[i].size()) {
      int id = s[i][j] - 'a';
      S.pop_back();
      if (!exist[id]) {
        exist[id] = true;
        data[id].append(S);
      }
    }
  }
  ll res = 0;
  rep(i, N) {
    int id = *s[i].rbegin() - 'a';
    s[i].pop_back();
    res += data[id].ans(s[i]) - 1;
  }
  cout << res << endl;
}