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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 200005;
const int maxlen = 1000005;
const int kcz = 998244353;
struct HasH {
  // int l;
  ull val1;
  // ll val2;
  HasH(/*int l=0,*/ ull val1 = 0 /*,ll val2=0*/)
      : /*l(l),*/ val1(val1) /*,val2(val2)*/ {}
  inline bool operator<(const HasH &h) const {
    return /*(l!=h.l)?l<h.l:((val1!=h.val1)?val1<h.val1:(val2<h.val2))*/ (
        val1 < h.val1);
  }
  inline HasH operator+(const char &ch) const {
    return HasH(/*l+1,*/ val1 * 47 + ch - 'a' + 3 /*,(val2*39+ch-'a'+7)%kcz*/);
  }
  // inline void print() { printf("%d %llu %lld\\n",l,val1,val2); }
} suf[maxlen];
char temp[maxlen];
string s[maxn];
int n, id[maxn], len[maxn], pre[maxlen], cnt[26][maxlen], tot;
map<HasH, ll> ma;
inline bool cmp(int x, int y) { return len[x] < len[y]; }
int main() {
  register int i, j, k, t;
  ll ans = 0;
  scanf("%d", &n);
  for (i = 0; i < n; i++)
    scanf("%s", temp), s[i] = temp, len[i] = s[i].size(), id[i] = i;
  sort(id, id + n, cmp);
  ma.clear();
  tot = 0;
  memset(cnt, 0, sizeof(cnt));
  for (i = n - 1; i >= 0; i--) {
#define i id[i]
    suf[len[i]] = HasH();
    for (j = len[i] - 1; j >= 0; j--)
      suf[j] = suf[j + 1] + s[i][j];
    for (j = 0, pre[0] = 0; j < len[i]; j++)
      pre[j + 1] = pre[j] | (1 << (s[i][j] - 'a'));
    if (ma.count(suf[1]))
      ans += cnt[s[i][0] - 'a'][ma[suf[1]]];
    // suf[0].print();
    // printf("%s %lld\\n",s[i].c_str(),cnt[suf[0]]);
    for (j = 0; j <= len[i]; j++) {
      if (pre[j] && !ma.count(suf[j]))
        t = ma[suf[j]] = ++tot;
      else
        t = ma[suf[j]];
      for (k = 0; k < 26; k++)
        if ((pre[j] >> k) & 1)
          cnt[k][t]++;
    }
    //         cnt[suf[j]+(k+'a')]+=1;//(suf[j]+(k+'a')).print();
  }
  printf("%lld\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 200005;
const int maxlen = 1000005;
const int kcz = 998244353;
struct HasH {
  // int l;
  ull val1;
  // ll val2;
  HasH(/*int l=0,*/ ull val1 = 0 /*,ll val2=0*/)
      : /*l(l),*/ val1(val1) /*,val2(val2)*/ {}
  inline bool operator<(const HasH &h) const {
    return /*(l!=h.l)?l<h.l:((val1!=h.val1)?val1<h.val1:(val2<h.val2))*/ (
        val1 < h.val1);
  }
  inline HasH operator+(const char &ch) const {
    return HasH(/*l+1,*/ val1 * 47 + ch - 'a' + 3 /*,(val2*39+ch-'a'+7)%kcz*/);
  }
  // inline void print() { printf("%d %llu %lld\\n",l,val1,val2); }
} suf[maxlen];
char temp[maxlen];
string s[maxn];
int n, id[maxn], len[maxn], pre[maxlen];
map<HasH, ll> cnt;
inline bool cmp(int x, int y) { return len[x] < len[y]; }
int main() {
  register int i, j, k;
  ll ans = 0;
  scanf("%d", &n);
  for (i = 0; i < n; i++)
    scanf("%s", temp), s[i] = temp, len[i] = s[i].size(), id[i] = i;
  sort(id, id + n, cmp);
  cnt.clear();
  for (i = n - 1; i >= 0; i--) {
#define i id[i]
    suf[len[i]] = HasH();
    for (j = len[i] - 1; j >= 0; j--)
      suf[j] = suf[j + 1] + s[i][j];
    for (j = 0, pre[0] = 0; j < len[i]; j++)
      pre[j + 1] = pre[j] | (1 << (s[i][j] - 'a'));
    ans += cnt[suf[0]];
    // suf[0].print();
    // printf("%s %lld\\n",s[i].c_str(),cnt[suf[0]]);
    for (j = 0; j <= len[i]; j++)
      for (k = 0; k < 26; k++)
        if ((pre[j] >> k) & 1)
          cnt[suf[j] + (k + 'a')] += 1; //(suf[j]+(k+'a')).print();
  }
  printf("%lld\\n", ans);
  return 0;
}