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

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

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ll> vi;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    pbds;

const int MOD[2] = {int(1e9 + 7), 998244353};
const int C[2] = {129381, 109239};

int mult(int a, int b, int mod) { return (a * 1LL * b) % mod; }

int add(int a, int b, int mod) {
  a += b;
  while (a >= mod)
    a -= mod;
  return a;
}

int exlen[1111111];

ll make(int a, int b) { return (a * 1LL * (MOD[0] + 10) + b); }

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<string> vec;
  set<int> L;
  vector<ll> hashes(n);
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    vec.pb(s);
    L.insert(int(s.length()));
    exlen[int(s.length()) - 1] = 1;
  }
  // unordered_map<ll,int> dp[26];
  vector<pair<ll, int>> badbits;
  for (int i = 0; i < n; i++) {
    string s = vec[i];
    int ct[26] = {};
    int len = s.length();
    int bit = 0;
    for (int j = 0; j < len; j++) {
      ct[s[j] - 'a']++;
      bit |= (1 << (s[j] - 'a'));
    }
    int hsh[2] = {0, 0};
    if (exlen[0]) {
      badbits.pb({0, bit});
    }
    /*
    for(int k=0;k<26;k++)
    {
            if(bit&(1<<k)) dp[k][0]++;
    }
    */
    if (len == 1) {
      hashes[i] = 0;
    }
    for (int j = len - 1; j >= 0; j--) {
      ct[s[j] - 'a']--;
      if (ct[s[j] - 'a'] == 0) {
        bit ^= (1 << (s[j] - 'a'));
      }
      for (int z = 0; z < 2; z++) {
        hsh[z] = mult(hsh[z], C[z], MOD[z]);
        hsh[z] = add(hsh[z], s[j], MOD[z]);
      }
      if (exlen[len - j]) {
        badbits.pb({make(hsh[0], hsh[1]), bit});
        /*
        for(int k=0;k<26;k++)
        {
                if(bit&(1<<k)) dp[k][make(hsh[0],hsh[1])]++;
        }
        */
      }
      if (j == 1) {
        hashes[i] = make(hsh[0], hsh[1]);
      }
    }
  }
  // all strings distinct
  ll ans = 0;
  vector<ll> dhashes;
  for (auto X : badbits)
    dhashes.pb(X.fi);
  for (int i = 0; i < n; i++)
    dhashes.pb(hashes[i]);
  sort(dhashes.begin(), dhashes.end());
  dhashes.erase(unique(dhashes.begin(), dhashes.end()));
  vector<int> dp[26];
  for (int i = 0; i < 26; i++)
    dp[i].resize(dhashes.size() + 1, 0);
  for (int i = 0; i < n; i++) {
    // suppose i am smaller
    ll tmp = hashes[i];
    int id = lower_bound(dhashes.begin(), dhashes.end(), tmp) - dhashes.begin();
    int ch = vec[i][0] - 'a';
    dp[ch][id]++;
    // ans+=dp[ch][tmp]-1;
  }
  for (auto X : badbits) {
    X.fi = lower_bound(dhashes.begin(), dhashes.end(), X.fi) - dhashes.begin();
    for (int i = 0; i < 26; i++) {
      if (X.se & (1 << i)) {
        ans += dp[i][X.fi];
      }
    }
  }
  ans -= n;
  cout << ans << '\\n';
}


Error: TLE

Fixed submission:

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

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ll> vi;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    pbds;

const int MOD[2] = {int(1e9 + 7), 998244353};
const int C[2] = {129381, 109239};

int mult(int a, int b, int mod) { return (a * 1LL * b) % mod; }

int add(int a, int b, int mod) {
  a += b;
  while (a >= mod)
    a -= mod;
  return a;
}

int exlen[1111111];

ll make(int a, int b) { return (a * 1LL * (MOD[0] + 10) + b); }

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<string> vec;
  set<int> L;
  vector<ll> hashes(n);
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    vec.pb(s);
    L.insert(int(s.length()));
    exlen[int(s.length()) - 1] = 1;
  }
  // unordered_map<ll,int> dp[26];
  vector<pair<ll, int>> badbits;
  for (int i = 0; i < n; i++) {
    string s = vec[i];
    int ct[26] = {};
    int len = s.length();
    int bit = 0;
    for (int j = 0; j < len; j++) {
      ct[s[j] - 'a']++;
      bit |= (1 << (s[j] - 'a'));
    }
    int hsh[2] = {0, 0};
    if (exlen[0]) {
      badbits.pb({0, bit});
    }
    /*
    for(int k=0;k<26;k++)
    {
            if(bit&(1<<k)) dp[k][0]++;
    }
    */
    if (len == 1) {
      hashes[i] = 0;
    }
    for (int j = len - 1; j >= 0; j--) {
      ct[s[j] - 'a']--;
      if (ct[s[j] - 'a'] == 0) {
        bit ^= (1 << (s[j] - 'a'));
      }
      for (int z = 0; z < 2; z++) {
        hsh[z] = mult(hsh[z], C[z], MOD[z]);
        hsh[z] = add(hsh[z], s[j], MOD[z]);
      }
      if (exlen[len - j]) {
        badbits.pb({make(hsh[0], hsh[1]), bit});
        /*
        for(int k=0;k<26;k++)
        {
                if(bit&(1<<k)) dp[k][make(hsh[0],hsh[1])]++;
        }
        */
      }
      if (j == 1) {
        hashes[i] = make(hsh[0], hsh[1]);
      }
    }
  }
  // all strings distinct
  ll ans = 0;
  unordered_map<ll, int> dp[26];
  for (int i = 0; i < n; i++) {
    // suppose i am smaller
    ll tmp = hashes[i];
    int ch = vec[i][0] - 'a';
    dp[ch][tmp]++;
    // ans+=dp[ch][tmp]-1;
  }
  for (auto X : badbits) {
    for (int i = 0; i < 26; i++) {
      if (X.se & (1 << i)) {
        ans += dp[i][X.fi];
      }
    }
  }
  ans -= n;
  cout << ans << '\\n';
}