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

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set                                                            \\
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
#define ld long double
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(a) a.begin(), a.end()
#define sz(a) (ll)(a.size())
const ll pa = 31, pb = 257, moda = 1e9 + 7, modb = 998244353;
const int M = 30;
int ct[M];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  vector<pair<int, int>> res;
  ll ans = 0;
  vector<pair<int, int>> vec;
  for (int i = 1; i <= n; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < 26; j++)
      ct[j] = 0;
    for (int j = 0; j < sz(s); j++)
      ct[s[j] - 'a']++;
    ll ha = 0, hb = 0;
    for (int j = sz(s) - 1; j >= 0; j--) {
      for (int p = 0; p < 26; p++) {
        if (ct[p]) {
          ll z = p + 1;
          int nha = (ha * pa + z) % moda;
          int nhb = (hb * pb + z) % modb;
          res.pb({nha, nhb});
        }
      }
      ll z = s[j] - 'a' + 1;
      ha = (ha * pa + z) % moda;
      hb = (hb * pb + z) % modb;
      ct[s[j] - 'a']--;
    }
    vec.pb({ha, hb});
  }
  sort(all(vec));
  sort(all(res));
  int j = 0;
  ll val = 0;
  for (int i = 0; i < sz(vec); i++) {
    if (i && vec[i] == vec[i - 1]) {
      ans += val;
      continue;
    }
    val = 0;
    while (j < sz(res) && res[j] < vec[i])
      j++;
    // cout<<res[j].ff<<" "<<res[j].ss<<" "<<vec[i].ff<<" "<<vec[i].ss<<endl;
    while (j < sz(res) && res[j] == vec[i]) {
      j++;
      val++;
    }
    ans += val;
  }
  ans -= n;
  cout << ans << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set                                                            \\
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
#define ld long double
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(a) a.begin(), a.end()
#define sz(a) (ll)(a.size())
const ll pa = 31, pb = 257, moda = 1e9 + 7, modb = 998244353;
const int M = 30;
int ct[M];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  map<pair<int, int>, int> H;
  ll ans = 0;
  vector<pair<int, int>> vec;
  for (int i = 1; i <= n; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < 26; j++)
      ct[j] = 0;
    for (int j = 0; j < sz(s); j++)
      ct[s[j] - 'a']++;
    ll ha = 0, hb = 0;
    for (int j = sz(s) - 1; j >= 0; j--) {
      for (int p = 0; p < 26; p++) {
        if (ct[p]) {
          ll z = p + 1;
          int nha = (ha * pa + z) % moda;
          int nhb = (hb * pb + z) % modb;
          H[{nha, nhb}]++;
        }
      }
      ll z = s[j] - 'a' + 1;
      ha = (ha * pa + z) % moda;
      hb = (hb * pb + z) % modb;
      ct[s[j] - 'a']--;
    }
    vec.pb({ha, hb});
  }
  for (auto u : vec)
    ans += H[u] - 1;
  cout << ans << "\\n";
  return 0;
}