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

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define ldb double
template <typename T> void ckmn(T &a, T b) { a = min(a, b); }
template <typename T> void ckmx(T &a, T b) { a = max(a, b); }
const int N = 1000050;
int go[N][26], root, tsz, w[N];
void Add(string s) {
  if (!root)
    root = ++tsz;
  int now = root;
  for (char c : s) {
    if (!go[now][c - 'a'])
      go[now][c - 'a'] = ++tsz;
    now = go[now][c - 'a'];
  }
  w[now]++;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  vector<string> v(n);
  for (auto &s : v)
    cin >> s;
  vector<int> idx;
  for (int i = 0; i < n; i++)
    idx.pb(i);
  sort(idx.begin(), idx.end(),
       [&](int i, int j) { return v[i].size() < v[j].size(); });
  int ans = 0;
  for (int j : idx) {
    string s = v[j];
    vector<int> cnt(26, 0);
    for (char c : s)
      cnt[c - 'a']++;
    int now = root;
    for (int i = (int)s.size() - 1; i >= 0; i--) {
      for (int z = 0; z < 26; z++) {
        if (cnt[z])
          ans += w[go[now][z]];
      }
      cnt[s[i] - 'a']--;
      now = go[now][s[i] - 'a'];
    }
    reverse(s.begin(), s.end());
    Add(s);
  }
  cout << ans << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define pii pair<int, int>
#define ldb double
template <typename T> void ckmn(T &a, T b) { a = min(a, b); }
template <typename T> void ckmx(T &a, T b) { a = max(a, b); }
void rd(int &x) { scanf("%i", &x); }
void rd(ll &x) { scanf("%lld", &x); }
void rd(char *x) { scanf("%s", x); }
void rd(ldb &x) { scanf("%lf", &x); }
void rd(string &x) { scanf("%s", &x); }
template <typename T1, typename T2> void rd(pair<T1, T2> &x) {
  rd(x.first);
  rd(x.second);
}
template <typename T> void rd(vector<T> &x) {
  for (T &i : x)
    rd(i);
}
template <typename T, typename... A> void rd(T &x, A &...args) {
  rd(x);
  rd(args...);
}
template <typename T> void rd() {
  T x;
  rd(x);
  return x;
}
int ri() {
  int x;
  rd(x);
  return x;
}
template <typename T> vector<T> rv(int n) {
  vector<T> x(n);
  rd(x);
  return x;
}
const int mod1 = 998244353;
const int mod2 = 1e9 + 9;
const int base1 = 99999437;
const int base2 = 77777777;
pii operator+(pii a, pii b) {
  a.first += b.first;
  if (a.first >= mod1)
    a.first -= mod1;
  a.second += b.second;
  if (a.second >= mod2)
    a.second -= mod2;
  return a;
}
pii operator*(pii a, pii b) {
  a.first = (ll)a.first * b.first % mod1;
  a.second = (ll)a.second * b.second % mod2;
  return a;
}
pii operator-(pii a, pii b) { return a + mp(mod1 - b.first, mod2 - b.second); }
const int N = 1000050;
pii pw[N];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  pii base = mp(base1, base2);
  pw[0] = {1, 1};
  for (int i = 1; i < N; i++)
    pw[i] = pw[i - 1] * base;
  int n;
  cin >> n;
  vector<string> v(n);
  for (auto &s : v)
    cin >> s;
  // for(auto a:v)printf("%s\\n",a);
  // printf(":D\\n");
  sort(v.begin(), v.end(), [&](string a, string b) {
    return a.size() < b.size() || a.size() == b.size() && a < b;
  });
  // printf(":D\\n");
  map<pii, int> cnt;
  ll ans = 0;
  for (string s : v) {
    // printf("%s\\n",s);
    // cout<<s<<"\\n";
    pii hsh = {0, 0};
    for (int i = 0; i < s.size(); i++) {
      hsh = (hsh * base) + mp(s[i] - 'a' + 1, s[i] - 'a' + 1);
    }
    pii tmp = hsh;
    set<char> has;
    for (int i = 0; i < s.size(); i++) {
      tmp = tmp -
            (mp(s[i] - 'a' + 1, s[i] - 'a' + 1) * pw[(int)s.size() - i - 1]);
      has.insert(s[i]);
      for (char c : has) {
        pii now =
            tmp + (mp(c - 'a' + 1, c - 'a' + 1) * pw[(int)s.size() - i - 1]);
        ans += cnt[now];
      }
    }
    cnt[hsh]++;
  }
  // printf("%lld\\n",ans);
  cout << ans << "\\n";
  return 0;
}