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

#include <bits/stdc++.h>
#define Int int64_t

using namespace std;

template <char start, int C> struct Trie {
  struct Node {
    vector<int> nxt, accept;
    int exist;
    Node() : exist(0) { nxt.assign(C, -1); }
  };

  vector<Node> nodes;
  int root;
  Trie() : root(0) { nodes.push_back(Node()); }

  int count() const { return nodes[0].exist; }
  int size() const { return (int)nodes.size(); }

  void update_direct(int node, int id) { nodes[node].accept.push_back(id); }
  void update_child(int node, int child, int id) { ++nodes[node].exist; }

  void add(const string &str, int str_index, int node_index, int id) {
    if (str_index == str.size()) {
      update_direct(node_index, id);
      return;
    }
    int c = str[str_index] - start;
    if (nodes[node_index].nxt[c] == -1) {
      nodes[node_index].nxt[c] = (int)nodes.size();
      nodes.push_back(Node());
    }
    add(str, str_index + 1, nodes[node_index].nxt[c], id);
    update_child(node_index, nodes[node_index].nxt[c], id);
  }
  void add(const string &str, int id) { add(str, 0, 0, id); }
  void add(const string &str) { add(str, nodes[0].exist); }

  int find(const string &str) {
    int node_index = 0;
    for (auto c : str) {
      node_index = nodes[node_index].nxt[c - start];
      if (node_index < 0) {
        return node_index;
      }
    }
    return node_index;
  }
};

int main() {
  int N;
  cin >> N;
  vector<string> S(N);
  for (int i = 0; i < N; ++i) {
    cin >> S[i];
    reverse(S[i].begin(), S[i].end());
  }

  Trie<'a', 26> trie;
  for (int i = 0; i < N; ++i) {
    trie.add(S[i]);
  }

  vector<vector<int>> vec(trie.size(), vector<int>(26, 0));
  for (auto s : S) {
    int idx = trie.find(s.substr(0, s.size() - 1));
    ++vec[idx][s.back() - 'a'];
  }

  Int ans = -N;
  for (auto s : S) {
    int now = 0;
    vector<int> tmp(26, 0);
    for (int i = 0; i < s.size(); ++i) {
      for (int j = 0; j < 26; ++j) {
        tmp[j] += vec[now][j];
      }
      int c = s[i] - 'a';
      ans += tmp[c];
      tmp[c] = 0;
      now = trie.nodes[now].nxt[c];
    }
  }
  cout << ans << "\\n";

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define Int int64_t

using namespace std;

int main() {
  int N;
  cin >> N;
  vector<string> S(N);
  for (int i = 0; i < N; ++i) {
    cin >> S[i];
  }

  sort(S.begin(), S.end(), [](auto s, auto t) {
    if (s.size() == t.size()) {
      return s < t;
    }
    return s.size() < t.size();
  });

  // contain[i][j][k] := S[i]について, j番目までに文字kを含んでいる
  vector<vector<vector<bool>>> contain(N);
  for (int i = 0; i < N; ++i) {
    vector<vector<bool>> tmp(S[i].size(), vector<bool>(26, false));
    for (int j = 0; j < S[i].size(); ++j) {
      tmp[j][S[i][j] - 'a'] = true;
      if (j == 0) {
        continue;
      }
      for (int k = 0; k < 26; ++k) {
        tmp[j][k] = tmp[j][k] | tmp[j - 1][k];
      }
    }
    contain[i] = tmp;
  }

  map<string, vector<bool>> mp;
  Int ans = 0;
  for (int i = 0; i < N; ++i) {
    int n = S[i].size();
    for (int j = n; j > 0; --j) {
      string s = S[i].substr(j);
      if (!mp.count(s)) {
        continue;
      }
      for (int k = 0; k < 26; ++k) {
        ans += (contain[i][j - 1][k] && mp[s][k]);
      }
    }
    string s = S[i].substr(1);
    if (!mp.count(s)) {
      mp[s] = vector<bool>(26, false);
    }
    mp[s][S[i][0] - 'a'] = true;
  }
  cout << ans << "\\n";

  return 0;
}