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

/*input
6
b
a
abc
c
d
ab
*/

// Nihesh Anderson - knandy

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

typedef long long ll;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set; // find_by_order, order_of_key
ll MOD = 1000000007;

#define endl '\\n'
#define fast_cin()                                                             \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define pb push_back
ll INF = 2000000000000000001;
long double EPS = 1e-9;
ll power(ll a, ll n, ll md) {
  if (n == 0) {
    return 1;
  } else {
    ll res = power(a, n / 2, md);
    res = (res * res) % md;
    if (n % 2 != 0) {
      res = (res * a) % md;
    }
    return res;
  }
}
random_device rndm;
mt19937 grndm(rndm());
void mix(ll *a, ll *b) { shuffle(a, b, grndm); }

const ll P = 31;
const ll MX = 1000005;

ll pwr[MX];
map<pair<ll, ll>, vector<ll>> f;
vector<string> v;

int main() {
  fast_cin();
  // freopen("input.in","r",stdin);
  // freopen("output.out","w",stdout);
  ll n;
  cin >> n;
  pwr[0] = 1;
  for (ll i = 1; i < MX; i++) {
    pwr[i] = (P * pwr[i - 1]) % MOD;
  }
  ll ans = 0;
  for (ll i = 0; i < n; i++) {
    string s;
    cin >> s;
    v.push_back(s);
  }
  sort(v.begin(), v.end(),
       [&](string &a, string &b) -> bool { return a.size() > b.size(); });
  for (auto s : v) {
    vector<ll> freq(26);
    for (auto c : s) {
      freq[c - 'a']++;
    }
    ll hash = 0;
    for (ll j = s.size() - 1; j >= 0; j--) {
      if (!f.count({hash, s.size() - 1 - j})) {
        f[{hash, s.size() - 1 - j}] = vector<ll>(26);
      }
      auto now = &f[{hash, s.size() - 1 - j}];
      for (ll k = 0; k < 26; k++) {
        if (freq[k])
          ((*now)[k])++;
      }
      if (j) {
        freq[s[j] - 'a']--;
        hash = (hash + (ll)(s[j]) * (pwr[s.size() - 1 - j])) % MOD;
      }
    }
    auto val = f[{hash, s.size() - 1}];
    ll match = s[0] - 'a';
    ans += (val[match] - 1);
  }
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

/*input
3
abcxyx
cyx
abc
*/

// Nihesh Anderson - knandy

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

typedef long long ll;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set; // find_by_order, order_of_key
ll MOD = 1000000009;

#define endl '\\n'
#define fast_cin()                                                             \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define pb push_back
ll INF = 2000000000000000001;
long double EPS = 1e-9;
ll power(ll a, ll n, ll md) {
  if (n == 0) {
    return 1;
  } else {
    ll res = power(a, n / 2, md);
    res = (res * res) % md;
    if (n % 2 != 0) {
      res = (res * a) % md;
    }
    return res;
  }
}
random_device rndm;
mt19937 grndm(rndm());
void mix(ll *a, ll *b) { shuffle(a, b, grndm); }

const ll P = 31;
const ll MX = 1000005;

ll pwr[MX];
map<pair<ll, ll>, vector<vector<ll>>> f;
vector<string> v;

int main() {
  fast_cin();
  // freopen("input.in","r",stdin);
  // freopen("output.out","w",stdout);
  ll n;
  cin >> n;
  pwr[0] = 1;
  for (ll i = 1; i < MX; i++) {
    pwr[i] = (P * pwr[i - 1]) % MOD;
  }
  ll ans = 0;
  for (ll i = 0; i < n; i++) {
    string s;
    cin >> s;
    v.push_back(s);
  }
  sort(v.begin(), v.end(),
       [&](string &a, string &b) -> bool { return a.size() > b.size(); });
  for (auto s : v) {
    vector<ll> freq(26);
    for (auto c : s) {
      freq[c - 'a']++;
    }
    ll hash = 0;
    for (ll j = s.size() - 1; j >= 0; j--) {
      f[{hash, s.size() - 1 - j}].push_back(freq);
      if (j) {
        freq[s[j] - 'a']--;
        hash = (hash + (ll)(s[j] - 'a' + 1) * (pwr[s.size() - 1 - j])) % MOD;
      }
    }
    auto val = f[{hash, s.size() - 1}];
    ll match = s[0] - 'a';
    for (ll i = 0; i < val.size() - 1; i++) {
      ans += (val[i][match] > 0);
    }
  }
  cout << ans << endl;
  return 0;
}