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

#pragma GCC optimize("Ofast")
#pragma GCC target("avx2", "sse4")
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

const int mxn = 2e5 + 5, mxm = 1e6 + 5;
const int ml0 = 1047961, mo0 = 1048505167;
const int ml1 = 1027127, mo1 = 1010521781;

int n;
char s[mxm];
int pw0[mxm], pw1[mxm];
int bg[mxn], ln[mxn];
int hs0[mxm], hs1[mxm];
int h0[mxn], h1[mxn];

/*
#include <bits/extc++.h>
using namespace __gnu_pbds;
gp_hash_table <ll, int> S;
*/

// /*
struct hashMap {
  static const int mxn = 19260817;
  int hd[mxn];
  vector<int> nex;
  vector<ll> key;
  vector<int> val;
  hashMap() {
    memset(hd, -1, sizeof(hd));
    nex.clear();
    key.clear();
    val.clear();
  }
#define fore(e, id) for (int e = hd[id]; ~e; e = nex[e])
  int &operator[](ll x) {
    int id = x % mxn;
    fore(e, id) if (key[e] == x) return val[e];
    key.pb(x);
    nex.pb(hd[id]);
    hd[id] = nex.size() - 1;
    val.pb(0);
    return val[nex.size() - 1];
  }
  int get(ll x) {
    int id = x % mxn;
    fore(e, id) if (key[e] == x) return val[e];
    return 0;
  }
#undef fore
};

hashMap S;
// */

bool hav[mxm];

int main() {
  rep(i, mxm) pw0[i] = i ? 1LL * pw0[i - 1] * ml0 % mo0 : 1;
  rep(i, mxm) pw1[i] = i ? 1LL * pw1[i - 1] * ml1 % mo1 : 1;
  scanf("%d", &n);
  // n = 2e5;
  rep(i, n) {
    bg[i] = i ? bg[i - 1] + ln[i - 1] : 0;
    scanf("%s", s + bg[i]);
    // rep(j, 1e6 / n) s[bg[i] + j] = rand() % 26 + 'a';
    ln[i] = strlen(s + bg[i]);
    h0[i] = h1[i] = 0;
    for (int j = ln[i] - 1; ~j; --j) {
      h0[i] = (h0[i] + 1LL * pw0[ln[i] - 1 - j] * s[bg[i] + j]) % mo0;
      h1[i] = (h1[i] + 1LL * pw1[ln[i] - 1 - j] * s[bg[i] + j]) % mo1;
      hs0[bg[i] + j] = h0[i];
      hs1[bg[i] + j] = h1[i];
    }
    hav[ln[i]] = 1;
    S[1LL * h0[i] * mo1 + h1[i]]++;
  }
  ll ans = 0;
  rep(i, n) {
    int cnt[26];
    memset(cnt, 0, sizeof(cnt));
    rep(j, ln[i]) {
      cnt[s[bg[i] + j] - 'a']++;
      int rs = ln[i] - j - 1;
      int rh0 = rs ? hs0[bg[i] + j + 1] : 0;
      int rh1 = rs ? hs1[bg[i] + j + 1] : 0;
      if (!hav[rs + 1])
        continue;
      rep(c, 26) if (cnt[c]) {
        int nh0 = (1LL * (c + 'a') * pw0[rs] + rh0) % mo0;
        int nh1 = (1LL * (c + 'a') * pw1[rs] + rh1) % mo1;
        if (j)
          ans += S.get(1LL * nh0 * mo1 + nh1);
      }
    }
  }
  printf("%lld\\n", ans);
  return 0;
}


Error: TLE

Fixed submission:

#pragma GCC optimize("Ofast")
#pragma GCC target("avx2", "sse4")
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

const int mxn = 2e5 + 5, mxm = 1e6 + 5;
const int ml0 = 1047961, mo0 = 1048505167;
const int ml1 = 1027127, mo1 = 1010521781;

int n;
char s[mxm];
int pw0[mxm], pw1[mxm];
int bg[mxn], ln[mxn];
int hs0[mxm], hs1[mxm];
int h0[mxn], h1[mxn];

/*
#include <bits/extc++.h>
using namespace __gnu_pbds;
gp_hash_table <ll, int> S;
*/

// /*
struct hashMap {
  static const int mxn = 19260817;
  int hd[mxn];
  vector<int> nex;
  vector<ll> key;
  vector<int> val;
  hashMap() {
    memset(hd, -1, sizeof(hd));
    nex.clear();
    key.clear();
    val.clear();
  }
#define fore(e, id) for (int e = hd[id]; ~e; e = nex[e])
  int &operator[](ll x) {
    int id = x % mxn;
    fore(e, id) if (key[e] == x) return val[e];
    key.pb(x);
    nex.pb(hd[id]);
    hd[id] = nex.size() - 1;
    val.pb(0);
    return val[nex.size() - 1];
  }
#undef fore
};

hashMap S;
// */

bool hav[mxm];

int main() {
  rep(i, mxm) pw0[i] = i ? 1LL * pw0[i - 1] * ml0 % mo0 : 1;
  rep(i, mxm) pw1[i] = i ? 1LL * pw1[i - 1] * ml1 % mo1 : 1;
  scanf("%d", &n);
  // n = 2e0;
  rep(i, n) {
    bg[i] = i ? bg[i - 1] + ln[i - 1] : 0;
    scanf("%s", s + bg[i]);
    // rep(j, 1e6 / n) s[bg[i] + j] = rand() % 26 + 'a';
    ln[i] = strlen(s + bg[i]);
    h0[i] = h1[i] = 0;
    for (int j = ln[i] - 1; ~j; --j) {
      h0[i] = (h0[i] + 1LL * pw0[ln[i] - 1 - j] * s[bg[i] + j]) % mo0;
      h1[i] = (h1[i] + 1LL * pw1[ln[i] - 1 - j] * s[bg[i] + j]) % mo1;
      hs0[bg[i] + j] = h0[i];
      hs1[bg[i] + j] = h1[i];
    }
    hav[ln[i]] = 1;
    S[1LL * h0[i] * mo1 + h1[i]]++;
  }
  ll ans = 0;
  rep(i, n) {
    int cnt[26];
    memset(cnt, 0, sizeof(cnt));
    rep(j, ln[i]) {
      cnt[s[bg[i] + j] - 'a']++;
      int rs = ln[i] - j - 1;
      int rh0 = rs ? hs0[bg[i] + j + 1] : 0;
      int rh1 = rs ? hs1[bg[i] + j + 1] : 0;
      if (!hav[rs + 1])
        continue;
      rep(c, 26) if (cnt[c]) {
        int nh0 = (1LL * (c + 'a') * pw0[rs] + rh0) % mo0;
        int nh1 = (1LL * (c + 'a') * pw1[rs] + rh1) % mo1;
        if (j)
          ans += S[1LL * nh0 * mo1 + nh1];
      }
    }
  }
  printf("%lld\\n", ans);
  return 0;
}