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

#include <algorithm>
#include <array>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORR(i, a, b) for (int i = a; i >= b; --i)
#define ALL(c) (c).begin(), (c).end()

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<double> VD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;

template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}

int in() {
  int x;
  scanf("%d", &x);
  return x;
}
ll lin() {
  ll x;
  scanf("%lld", &x);
  return x;
}

int m = 1e6 + 1;

struct Trie {
  vector<array<int, 26>> trie_nodes = {{}};
  vector<int> sz = {0};
  vector<array<int, 26>> cnt = {{}};

  void push(string s) {
    VI last(26, -1);
    REP(i, s.length()) last[s[i] - 'a'] = i;
    int node = 0;
    sz[node]++;
    REP(j, 26) if (last[j] >= 0) cnt[node][j]++;
    REP(i, s.length()) {
      char c = s[i];
      int x = c - 'a';
      if (!trie_nodes[node][x]) {
        trie_nodes[node][x] = trie_nodes.size();
        trie_nodes.push_back({});
        sz.push_back(0);
        cnt.push_back({});
      }
      node = trie_nodes[node][x];
      sz[node]++;
      REP(j, 26) if (last[j] > i) cnt[node][j]++;
    }
  }

  int calc(string s) {
    int node = 0;
    REP(i, s.length() - 1) {
      char c = s[i];
      int x = c - 'a';
      if (!trie_nodes[node][x])
        return 0;
      node = trie_nodes[node][x];
    }
    return cnt[node][s.back() - 'a'];
  }
};

int main(void) {
  int n;
  cin >> n;
  vector<vector<string>> ss(m);
  REP(i, n) {
    string s;
    cin >> s;
    ss[s.length()].push_back(s);
  }

  Trie trie;
  ll ans = 0;

  FORR(n, m - 1, 1) {
    for (string s : ss[n]) {
      reverse(ALL(s));
      ans += trie.calc(s);
      trie.push(s);
    }
  }

  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORR(i, a, b) for (int i = a; i >= b; --i)
#define ALL(c) (c).begin(), (c).end()

typedef long long ll;
typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<double> VD;
typedef vector<VI> VVI;
typedef vector<VL> VVL;
typedef vector<VD> VVD;
typedef pair<int, int> P;
typedef pair<ll, ll> PL;

template <typename T> void chmin(T &a, T b) {
  if (a > b)
    a = b;
}
template <typename T> void chmax(T &a, T b) {
  if (a < b)
    a = b;
}

int in() {
  int x;
  scanf("%d", &x);
  return x;
}
ll lin() {
  ll x;
  scanf("%lld", &x);
  return x;
}

int m = 1e6 + 1;
ll mod1 = 1e9 + 7, mod2 = 1e9 + 9;
ll base1 = 1007, base2 = 1009;
VL hash1, hash2, pow1, pow2;

int main(void) {
  int n;
  cin >> n;
  vector<vector<string>> ss(m);
  REP(i, n) {
    string s;
    cin >> s;
    ss[s.length()].push_back(s);
  }

  map<pair<PL, int>, int> cnt;
  ll ans = 0;

  FOR(n, 1, m - 1) {
    for (string s : ss[n]) {
      VI first(26, 1e9);
      REP(i, n) { chmin(first[s[i] - 'a'], i); }
      PL hash;
      REP(i, n - 1) {
        REP(j, 26) {
          if (first[j] >= n - i)
            continue;
          ans += cnt[make_pair(hash, j)];
        }
        hash.first = (hash.first * base1 + s[n - 1 - i]) % mod1;
        hash.second = (hash.second * base2 + s[n - 1 - i]) % mod2;
      }
      cnt[make_pair(hash, s[0] - 'a')]++;
    }
  }

  cout << ans << endl;
  return 0;
}