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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int MOD = 1000000007;
//~ const int MOD=998244353;
const int INF = 0x3f3f3f3f;
const ll INFL = 0x3f3f3f3f3f3f3f3f;

typedef unsigned int uint;
template <class T, uint mod> struct RollingHash_ {
  vector<uint> hashed, power;

  inline uint mul(uint a, uint b) { return a * (unsigned long long)b % mod; }
  RollingHash_() {}
  RollingHash_(T s, uint base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  uint get(int l, int r) {
    uint ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }
};

string s[210000];
unordered_map<uint, unordered_map<int, int>> mp[1200000];
int cnt[26];
RollingHash_<string, 1000000007> rh[210000];
char S[2000000];

int main() {
  int n;
  cin >> n;
  rep(i, n) {
    scanf("%s", S);
    s[i] = S;
  }
  rep(i, n) {
    rh[i] = RollingHash_<string, 1000000007>(s[i]);
    mp[s[i].size()][rh[i].get(1, s[i].size())][s[i][0] - 'a']++;
  }
  ll ans = 0;
  rep(i, n) {
    memset(cnt, 0, sizeof(cnt));
    for (char c : s[i]) {
      cnt[c - 'a']++;
    }
    for (int j = s[i].size(); j >= 2; j--) {
      if (j != s[i].size())
        cnt[s[i][j] - 'a']--;
      int sz = s[i].size() - j;
      auto hs = rh[i].get(j, s[i].size());
      for (auto &p : mp[sz + 1][hs]) {
        if (cnt[p.first])
          ans += p.second;
      }
    }
  }
  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int MOD = 1000000007;
//~ const int MOD=998244353;
const int INF = 0x3f3f3f3f;
const ll INFL = 0x3f3f3f3f3f3f3f3f;

typedef unsigned int uint;
template <class T, uint mod> struct RollingHash_ {
  vector<uint> hashed, power;

  inline uint mul(uint a, uint b) { return a * (unsigned long long)b % mod; }
  RollingHash_() {}
  RollingHash_(T s, uint base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  uint get(int l, int r) {
    uint ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }
};

typedef pair<uint, uint> Hash;

template <class T> struct RollingHash {
  RollingHash_<T, 998244353> RH1;
  RollingHash_<T, 1000000007> RH2;

  RollingHash() {}
  RollingHash(T s) {
    RH1 = RollingHash_<T, 998244353>(s);
    RH2 = RollingHash_<T, 1000000007>(s);
  }

  Hash get(int l, int r) { return make_pair(RH1.get(l, r), RH2.get(l, r)); }
};

string s[210000];
unordered_map<int, unordered_map<uint, int>> mp[26];
int cnt[26];
RollingHash_<string, 1000000007> rh[210000];
char S[2000000];

int main() {
  int n;
  cin >> n;
  rep(i, n) {
    scanf("%s", S);
    s[i] = S;
  }
  rep(i, n) {
    rh[i] = RollingHash_<string, 1000000007>(s[i]);
    mp[s[i][0] - 'a'][s[i].size()][rh[i].get(1, s[i].size())]++;
  }
  ll ans = 0;
  rep(i, n) {
    memset(cnt, 0, sizeof(cnt));
    for (char c : s[i]) {
      cnt[c - 'a']++;
    }
    for (int j = s[i].size(); j >= 2; j--) {
      if (j != s[i].size())
        cnt[s[i][j] - 'a']--;
      int sz = s[i].size() - j;
      auto hs = rh[i].get(j, s[i].size());
      for (int k = 0; k < 26; k++) {
        if (cnt[k])
          ans += mp[k][sz + 1][hs];
      }
    }
  }
  cout << ans << endl;
}