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

#include <bits/stdc++.h>
using namespace ::std;
#define all(n) (n).begin(), (n).end()

auto meld(tuple<int, int, int> s, tuple<int, int, int> t) {
  constexpr int64_t base = 10007;
  constexpr int64_t mod[2] = {1000000007LL, 999999937LL};
  int64_t a[2] = {};
  a[0] = (int64_t(get<0>(s)) * base % mod[0] + get<0>(t)) % mod[0];
  a[1] = (int64_t(get<1>(s)) * base % mod[1] + get<1>(t)) % mod[1];
  return make_tuple(a[0], a[1], get<2>(s) + get<2>(t));
}
auto make(char c) { return make_tuple(int(c), int(c), 1); }
auto empty() { return make_tuple(0, 0, 0); }

int main() {
  vector<tuple<int, int, int>> m;
  int n;
  cin >> n;
  vector<tuple<int, int, int>> v(n, empty());
  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    reverse(all(s));
    vector<int> cnt(26, 0);
    for (int j = 0; j < (int)s.size(); ++j)
      cnt[s[j] - 'a']++;
    bitset<26> b;
    for (int j = 0; j < 26; ++j)
      if (cnt[j])
        b[j] = 1;
    for (int j = 0; j < (int)s.size(); ++j) {
      for (int k = b._Find_first(); k < 26; k = b._Find_next(k)) {
        auto e = meld(v[i], make(k + 'a'));
        m.push_back(e);
      }
      v[i] = meld(v[i], make(s[j]));
      cnt[s[j] - 'a']--;
      if (!cnt[s[j] - 'a'])
        b[s[j] - 'a'] = 0;
    }
  }
  sort(all(m));
  int64_t ans = 0;
  for (int i = 0; i < n; ++i) {
    ans += upper_bound(all(m), v[i]) - lower_bound(all(m), v[i]) - 1;
  }
  cout << ans << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace ::std;
#define all(n) (n).begin(), (n).end()
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// typedef mp::number<mp::cpp_dec_float<0>> cdouble;
// typedef mp::cpp_int cint;
template <typename T>
using pbds =
    __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag,
                     __gnu_pbds::tree_order_statistics_node_update>;
template <typename T>
using pbds_map =
    __gnu_pbds::tree<T, T, less<T>, __gnu_pbds::rb_tree_tag,
                     __gnu_pbds::tree_order_statistics_node_update>;
template <typename T, typename E>
using hash_map = __gnu_pbds::gp_hash_table<T, E>;
template <typename T>
using pqueue =
    __gnu_pbds::priority_queue<T, greater<T>, __gnu_pbds::rc_binomial_heap_tag>;

auto meld(tuple<int, int, int> s, tuple<int, int, int> t) {
  constexpr int64_t base = 10007;
  constexpr int64_t mod[2] = {1000000007LL, 999999937LL};
  int64_t a[2] = {};
  a[0] = (int64_t(get<0>(s)) * base % mod[0] + get<0>(t)) % mod[0];
  a[1] = (int64_t(get<1>(s)) * base % mod[1] + get<1>(t)) % mod[1];
  return make_tuple(a[0], a[1], get<2>(s) + get<2>(t));
}
auto make(char c) { return make_tuple(int(c), int(c), 1); }
auto empty() { return make_tuple(0, 0, 0); }

int main() {
  auto f = [](auto s) { return get<0>(s) ^ get<1>(s); };
  vector<__gnu_pbds::gp_hash_table<pair<int, int>, int, decltype(f)>> m(
      1000000,
      __gnu_pbds::gp_hash_table<tuple<int, int, int>, int, decltype(f)>(f));
  int n;
  cin >> n;
  vector<tuple<int, int, int>> v(n, empty());
  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    reverse(all(s));
    vector<int> cnt(26, 0);
    for (int j = 0; j < (int)s.size(); ++j)
      cnt[s[j] - 'a']++;
    bitset<26> b;
    for (int j = 0; j < 26; ++j)
      if (cnt[j])
        b[j] = 1;
    for (int j = 0; j < (int)s.size(); ++j) {
      for (int k = b._Find_first(); k < 26; k = b._Find_next(k)) {
        auto e = meld(v[i], make(k + 'a'));
        m[get<2>(e)][{get<0>(e), get<1>(e)}]++;
      }
      v[i] = meld(v[i], make(s[j]));
      cnt[s[j] - 'a']--;
      if (!cnt[s[j] - 'a'])
        b[s[j] - 'a'] = 0;
    }
  }
  int64_t ans = 0;
  for (int i = 0; i < n; ++i) {
    ans += m[get<2>(v[i])][{get<0>(v[i]), get<1>(v[i])}] - 1;
  }
  cout << ans << endl;
}