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

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
// ordered_set X;
// *X.find_by_order(i) = ith largest element (counting from zero)
// X.order_of_key(k) = number of items in X < k (strict lt)

constexpr ll P = 27;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int N;
  cin >> N;

  vs S(N);
  for (int i = 0; i < N; i++)
    cin >> S[i];

  // unordered_map<ll, int> right;
  // unordered_map<ll, int> zleft;
  // unordered_map<ll, int> zright;

  unordered_set<ll> left;
  for (const string &s : S) {
    ll cur = 0;
    int n = s.length();
    for (int i = 0; i < n; i++) {
      cur *= P;
      cur += (s[n - 1 - i] - 'a') + 1;
    }
    left.insert(cur);
  }

  ll ans = 0;
  for (const string &s : S) {
    vi freqs(26, 0);
    int n = s.length();
    for (int i = 0; i < n; i++)
      freqs[s[i] - 'a']++;

    // suffixes
    ll cur = 0;
    for (int i = 0; i <= n - 1; i++) {
      if (i < n - 1) {
        for (int j = 0; j < 26; j++) {
          if (freqs[j] > 0) {
            ll nxt = cur * P + (j + 1);
            if (left.find(nxt) != left.end())
              ans++;
          }
        }
      }

      cur *= P;
      cur += (s[n - 1 - i] - 'a') + 1;
      freqs[s[n - 1 - i] - 'a']--;
    }
  }

  cout << ans << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
// ordered_set X;
// *X.find_by_order(i) = ith largest element (counting from zero)
// X.order_of_key(k) = number of items in X < k (strict lt)

constexpr ll P = 27;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int N;
  cin >> N;

  vs S(N);
  for (int i = 0; i < N; i++)
    cin >> S[i];

  unordered_map<ll, int> right;
  // unordered_map<ll, int> zleft;
  // unordered_map<ll, int> zright;

  set<ll> left;

  for (const string &s : S) {
    vi freqs(26, 0);
    int n = s.length();
    for (int i = 0; i < n; i++)
      freqs[s[i] - 'a']++;

    // suffixes
    ll cur = 0;
    for (int i = 0; i <= n - 1; i++) {
      if (i < n - 1) {
        for (int j = 0; j < 26; j++) {
          if (freqs[j] > 0) {
            ll nxt = cur * P + (j + 1);
            if (right.find(nxt) != right.end())
              right[nxt]++;
            else
              right[nxt] = 1;
          }
        }
      }

      cur *= P;
      cur += (s[n - 1 - i] - 'a') + 1;
      freqs[s[n - 1 - i] - 'a']--;
    }

    left.insert(cur);
  }

  ll ans = 0;
  for (auto x : left) {
    if (right.find(x) != right.end())
      ans += right[x];
    // ans += get(right, x);
  }

  cout << ans << endl;

  return 0;
}