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

// #define _GLIBCXX_DEBUG
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
#define pp pair<int, int>
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define ld long double
#define al(a) (a).begin(), (a).end()
#define mk make_pair
#define check cout << "?" << endl;

ll MOD = 1000000007;
ll mod = 998244353;
int inf = 1000001000;
ll INF = 1e18 + 5;

class Rolliha {
public:
  using ull = unsigned long long int;
  using uint = unsigned int;
  const ull MASK30 = (1ULL << 30) - 1;
  const ull MASK31 = (1ULL << 31) - 1;
  const ull MOD_rh = (1ULL << 61) - 1;
  const ull POSITIVIZER = MOD_rh * ((1ULL << 3) - 1);

  int sz;
  vector<ull> hash_table, power; // 1-indexed

  Rolliha(const string &s, uint base = 0) : sz{(int)s.size()} {
    hash_table.assign(sz + 1, 0);
    power.assign(sz + 1, 1);

    random_device rd;
    uniform_int_distribution<uint> dist(129, numeric_limits<int>::max() - 1);
    if (base == 0)
      base = dist(rd);

    rep(i, sz) {
      power[i + 1] = mul(power[i], base);
      hash_table[i + 1] = mul(hash_table[i], base) + s[i];
      if (hash_table[i + 1] >= MOD_rh)
        hash_table[i + 1] -= MOD_rh;
    }
  }

  //(l,r] 1-indexedの場合
  ull sechash(int l, int r) {
    return calc_mod(hash_table[r] + POSITIVIZER -
                    mul(hash_table[l], power[r - l]));
  }

  // mod 2^61-1
  ull mul(ull a, ull b) {
    ull aq = a >> 31, bq = b >> 31;
    ull ar = a & MASK31, br = b & MASK31;
    ull mid = aq * br + ar * bq;
    ull midu = mid >> 30;
    ull midl = mid & MASK30;
    return ((aq * bq) << 1) + midu + (midl << 31) + ar * br;
  }

  ull mul(ull a, uint b) {
    ull aq = a >> 31;
    ull ar = a & MASK31, br = b & MASK31;
    ull mid = aq * br;
    ull midu = mid >> 30;
    ull midl = mid & MASK30;
    return midu + (midl << 31) + ar * br;
  }

  ull calc_mod(ull x) {
    ull xq = x >> 61;
    ull xr = x & MOD_rh;
    ull res = xq + xr;
    if (res >= MOD_rh)
      res -= MOD_rh;
    return res;
  }
};

int main() {
  int n;
  cin >> n;
  ll ans = 0;
  vector<pair<int, string>> s(n);
  rep(i, n) {
    string S;
    cin >> S;
    s[i] = mk(S.size(), S);
  }
  sort(al(s));
  vector<set<unsigned long long>> st(26);
  vector<int> cnt(26, 0);
  rep(i, n) {
    Rolliha rh{s[i].second, 1000000007U};
    int N = s[i].first;
    for (auto ch : s[i].second)
      cnt[ch - 'a']++;
    for (int j = N - 1; j >= 0; j--) {
      rep(k, 26) if (cnt[k]) ans += st[k].count(rh.sechash(j + 1, N));
      cnt[(s[i].second)[j] - 'a']--;
    }
    st[(s[i].second)[0] - 'a'].insert(rh.sechash(1, N));
  }
  cout << ans << endl;
}

Error: TLE

Fixed submission:

// #define _GLIBCXX_DEBUG
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
#define pp pair<int, int>
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define ld long double
#define al(a) (a).begin(), (a).end()
#define mk make_pair
#define check cout << "?" << endl;

ll MOD = 1000000007;
ll mod = 998244353;
int inf = 1000001000;
ll INF = 1e18 + 5;

class Rolliha {
public:
  using ull = unsigned long long int;
  using uint = unsigned int;
  const ull MASK30 = (1ULL << 30) - 1;
  const ull MASK31 = (1ULL << 31) - 1;
  const ull MOD_rh = (1ULL << 61) - 1;
  const ull POSITIVIZER = MOD_rh * ((1ULL << 3) - 1);

  int sz;
  vector<ull> hash_table, power; // 1-indexed

  Rolliha(const string &s, uint base = 0) : sz{(int)s.size()} {
    hash_table.assign(sz + 1, 0);
    power.assign(sz + 1, 1);

    random_device rd;
    uniform_int_distribution<uint> dist(129, numeric_limits<int>::max() - 1);
    if (base == 0)
      base = dist(rd);

    rep(i, sz) {
      power[i + 1] = mul(power[i], base);
      hash_table[i + 1] = mul(hash_table[i], base) + s[i];
      if (hash_table[i + 1] >= MOD_rh)
        hash_table[i + 1] -= MOD_rh;
    }
  }

  //(l,r] 1-indexedの場合
  ull sechash(int l, int r) {
    return calc_mod(hash_table[r] + POSITIVIZER -
                    mul(hash_table[l], power[r - l]));
  }

  // mod 2^61-1
  ull mul(ull a, ull b) {
    ull aq = a >> 31, bq = b >> 31;
    ull ar = a & MASK31, br = b & MASK31;
    ull mid = aq * br + ar * bq;
    ull midu = mid >> 30;
    ull midl = mid & MASK30;
    return ((aq * bq) << 1) + midu + (midl << 31) + ar * br;
  }

  ull mul(ull a, uint b) {
    ull aq = a >> 31;
    ull ar = a & MASK31, br = b & MASK31;
    ull mid = aq * br;
    ull midu = mid >> 30;
    ull midl = mid & MASK30;
    return midu + (midl << 31) + ar * br;
  }

  ull calc_mod(ull x) {
    ull xq = x >> 61;
    ull xr = x & MOD_rh;
    ull res = xq + xr;
    if (res >= MOD_rh)
      res -= MOD_rh;
    return res;
  }
};

int main() {
  int n;
  cin >> n;
  ll ans = 0;
  vector<pair<int, string>> s(n);
  rep(i, n) {
    string S;
    cin >> S;
    s[i] = mk(S.size(), S);
  }
  sort(al(s));
  vector<map<unsigned long long, int>> mp(26);
  vector<int> cnt(26, 0);
  rep(i, n) {
    Rolliha rh{s[i].second, 1000000007U};
    int N = s[i].first;
    for (auto ch : s[i].second)
      cnt[ch - 'a']++;
    for (int j = N - 1; j >= 0; j--) {
      rep(k, 26) if (cnt[k]) ans += mp[k][rh.sechash(j + 1, N)];
      cnt[(s[i].second)[j] - 'a']--;
    }
    mp[(s[i].second)[0] - 'a'][rh.sechash(1, N)]++;
  }
  cout << ans << endl;
}