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

#include <bits/stdc++.h>
#define mk make_pair
#define fs first
#define sc second
using namespace std;
typedef long long ll;
typedef long double ld;
// please, read the question correctly (do you need set or multiset)???
const int N = 200010; // check the limits, dummy
int a[N];
int n, m, cnt[44];
char s[1000010];
string c[N];
int mp1[5761455], mp2[5761537], mp3[5761543], mp4[5705543], mp5[5703199];
int main() {
  scanf("%d", &n);
  ll ans = 0, mod1 = 5761455, mod2 = 5761537, mod3 = 5761543, mod4 = 5705543,
     mod5 = 5703199;
  for (int i = 0; i < n; ++i) {
    scanf("%s", s);
    int sz = strlen(s);
    c[i] = s;
    int hsh2 = 0, hsh1 = 0, hsh3 = 0, hsh4 = 0, hsh5 = 0;
    for (int j = sz - 1; j >= 0; --j) {
      hsh1 *= 29;
      hsh1 += s[j] - 'a' + 1;
      hsh1 %= mod1;
      hsh2 *= 31;
      hsh2 += s[j] - 'a' + 1;
      hsh2 %= mod2;
      hsh3 *= 37;
      hsh3 += s[j] - 'a' + 1;
      hsh3 %= mod3;
      hsh4 *= 41;
      hsh4 += s[j] - 'a' + 1;
      hsh4 %= mod4;
      hsh5 *= 43;
      hsh5 += s[j] - 'a' + 1;
      hsh5 %= mod5;
    }
    ++mp1[hsh1];
    ++mp2[hsh2];
    ++mp3[hsh3];
    ++mp4[hsh4];
    ++mp5[hsh5];
  }
  for (int i = 0; i < n; ++i) {
    int sz = c[i].size();
    for (int j = 0; j < 26; ++j)
      cnt[j] = 0;
    for (int j = 0; j < sz; ++j) {
      ++cnt[c[i][j] - 'a'];
    }
    ll hsh3 = 0, hsh4 = 0, hsh1 = 0, hsh2 = 0, tmp1, tmp2, tmp3, tmp4, hsh5 = 0,
       tmp5;
    for (int j = sz - 1; j >= 0; --j) {
      for (int k = 0; k < 26; ++k) {
        if (cnt[k]) {
          tmp1 = hsh1 * 29;
          tmp1 += k + 1;
          tmp1 %= mod1;
          tmp2 = hsh2 * 31;
          tmp2 += k + 1;
          tmp2 %= mod2;
          tmp3 = hsh3 * 37;
          tmp3 += k + 1;
          tmp3 %= mod3;
          tmp4 = hsh4 * 41;
          tmp4 += k + 1;
          tmp4 %= mod4;
          tmp5 = hsh5 * 43;
          tmp5 += k + 1;
          tmp5 %= mod5;
          ans += min(min(min(mp3[tmp3], mp4[tmp4]), min(mp1[tmp1], mp2[tmp2])),
                     mp5[tmp5]);
        }
      }
      hsh1 *= 29;
      hsh1 += c[i][j] - 'a' + 1;
      hsh1 %= mod1;
      hsh2 *= 31;
      hsh2 += c[i][j] - 'a' + 1;
      hsh2 %= mod2;
      hsh3 *= 37;
      hsh3 += c[i][j] - 'a' + 1;
      hsh3 %= mod3;
      hsh4 *= 41;
      hsh4 += c[i][j] - 'a' + 1;
      hsh4 %= mod4;
      hsh5 *= 43;
      hsh5 += c[i][j] - 'a' + 1;
      hsh5 %= mod5;
      --cnt[c[i][j] - 'a'];
    }
  }
  ans -= n;
  cout << ans << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define mk make_pair
#define fs first
#define sc second
using namespace std;
typedef long long ll;
typedef long double ld;
// please, read the question correctly (do you need set or multiset)???
const int N = 200010; // check the limits, dummy
int a[N];
int n, m, cnt[44];
char s[1000010];
// struct hash_pair {
//     template <class T1, class T2>
//     size_t operator()(const pair<T1, T2>& p) const
//     {
//         auto hash1 = hash<T1>{}(p.first);
//         auto hash2 = hash<T2>{}(p.second);
//         return hash1*1000000000+hash2;
//     }
// };

unordered_map<ll, int> mp;
// int mp[33][1]
string c[N];
int main() {
  scanf("%d", &n);
  ll ans = 0, mod = 1e9 + 9, mod1 = 1e9 + 9;
  for (int i = 0; i < n; ++i) {
    scanf("%s", s);
    // for(int j=0; j<100000; ++j){
    // 	s[j]='a';
    // }
    // s[100000]='\\0';
    int sz = strlen(s);
    c[i] = s;
    ll hsh = 0, hsh1 = 0;
    for (int j = sz - 1; j >= 0; --j) {
      // cout<<s[j]-'a'<<endl;
      hsh *= 29;
      hsh += s[j] - 'a' + 1;
      // hsh%=mod;
      // while(hsh>=mod)hsh-=mod;
      // hsh1*=29;
      // hsh1+=s[j]-'a';
      // hsh1%=mod1;
    }
    // cout<<endl;
    ++mp[hsh];
    // cout<<hsh<<" "<<hsh1<<endl;
  }
  for (int i = 0; i < n; ++i) {
    // cout<<c[i]<<endl;
    int sz = c[i].size();
    for (int j = 0; j < 26; ++j)
      cnt[j] = 0;
    for (int j = 0; j < sz; ++j) {
      ++cnt[c[i][j] - 'a'];
    }
    ll hsh = 0, hsh1 = 0, tmp1, tmp2;
    for (int j = sz - 1; j >= 0; --j) {
      for (int k = 0; k < 26; ++k) {
        if (cnt[k]) {
          // cout<<k<<"&"<<endl;
          tmp1 = hsh * 29;
          tmp1 += k + 1;
          // while(tmp1>=mod)tmp1-=mod;
          // tmp1%=mod;
          // tmp2=hsh1*29;
          // tmp2+=k;
          // tmp2%=mod1;
          ans += mp[tmp1];
          // cout<<"#"<<tmp1<<" "<<tmp2<<endl;cout<<mp[mk(tmp1, tmp2)]<<endl;
        }
      }
      // cout<<c[i][j]-'a'<<"(((((((((("<<endl;
      hsh *= 29;
      hsh += c[i][j] - 'a' + 1;
      // hsh%=mod;
      // while(hsh>=mod)hsh-=mod;
      // hsh1*=29;
      // hsh1+=c[i][j]-'a';
      // hsh1%=mod1;
      --cnt[c[i][j] - 'a'];
    }
  }
  ans -= n;
  cout << ans << endl;
}