Problem p02589 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define ull unsigned ll
#define pint pair<int, int>
#define mk(x, y) make_pair(x, y)
#define fir first
#define sec second
#define Rep(x, y, z) for (int x = y; x <= z; ++x)
#define Red(x, y, z) for (int x = y; x >= z; --x)
using namespace std;
const int MAXN = 2e5 + 5, MAXM = 1e6 + 5, base = 13131;
char buf[1 << 12], *p1 = buf, *p2 = buf, nc;
int ny;
// inline char gc() {return
// p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<12,stdin),p1==p2)?EOF:*p1++;}
inline char gc() { return getchar(); }
inline int read() {
  int x = 0;
  ny = 1;
  while (nc = gc(), (nc < 48 || nc > 57) && nc != EOF)
    if (nc == 45)
      ny = -1;
  if (nc < 0)
    return nc;
  x = nc - 48;
  while (nc = gc(), 47 < nc && nc < 58 && nc != EOF)
    x = (x << 3) + (x << 1) + (nc ^ 48);
  return x * ny;
}
int n, vis[26];
ull Fpow[MAXM];
vector<ull> Has[MAXN];
string S[MAXN];
int len[MAXN];
unordered_map<ull, int> cnt[26];
int main() {
  //	freopen("std.in","r",stdin);
  //	freopen("std.out","w",stdout);
  n = read();
  Fpow[0] = 1;
  Rep(i, 1, MAXM - 1) Fpow[i] = Fpow[i - 1] * base;
  Rep(i, 1, n) {
    cin >> S[i];
    len[i] = S[i].size();
    Has[i].resize(len[i] + 1), Has[i][len[i]] = 0;
    for (int j = len[i] - 1; j >= 0; j--)
      Has[i][j] = Has[i][j + 1] + Fpow[len[i] - j - 1] * S[i][j];
    cnt[S[i][0] - 'a'][Has[i][1]]++;
  }
  ll ans = 0;
  Rep(i, 1, n) {
    Rep(c, 0, 25) vis[c] = 0;
    cnt[S[i][0] - 'a'][Has[i][1]]--;
    for (int j = 0; j <= len[i]; j++) {
      Rep(c, 0, 25) if (vis[c]) ans += cnt[c][Has[i][j]];
      vis[S[i][j] - 'a'] = 1;
    }
    cnt[S[i][0] - 'a'][Has[i][1]]++;
  }
  cout << ans << "\n";
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define ull unsigned ll
#define pint pair<int, int>
#define mk(x, y) make_pair(x, y)
#define fir first
#define sec second
#define Rep(x, y, z) for (int x = y; x <= z; ++x)
#define Red(x, y, z) for (int x = y; x >= z; --x)
using namespace std;
const int MAXN = 2e5 + 5, MAXM = 1e6 + 5, base = 13131;
char buf[1 << 12], *p1 = buf, *p2 = buf, nc;
int ny;
// inline char gc() {return
// p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<12,stdin),p1==p2)?EOF:*p1++;}
inline char gc() { return getchar(); }
inline int read() {
  int x = 0;
  ny = 1;
  while (nc = gc(), (nc < 48 || nc > 57) && nc != EOF)
    if (nc == 45)
      ny = -1;
  if (nc < 0)
    return nc;
  x = nc - 48;
  while (nc = gc(), 47 < nc && nc < 58 && nc != EOF)
    x = (x << 3) + (x << 1) + (nc ^ 48);
  return x * ny;
}
int n, vis[26];
ull Fpow[MAXM];
vector<ull> Has[MAXN];
string S[MAXN];
int len[MAXN];
unordered_map<ull, int> cnt[26];
int main() {
  //	freopen("std.in","r",stdin);
  //	freopen("std.out","w",stdout);
  n = read();
  Fpow[0] = 1;
  Rep(i, 1, MAXM - 1) Fpow[i] = Fpow[i - 1] * base;
  Rep(i, 1, n) {
    cin >> S[i];
    len[i] = S[i].size();
    Has[i].resize(len[i] + 1), Has[i][len[i]] = 0;
    for (int j = len[i] - 1; j >= 0; j--)
      Has[i][j] = Has[i][j + 1] + Fpow[len[i] - j - 1] * S[i][j];
    cnt[S[i][0] - 'a'][Has[i][1]]++;
  }
  ll ans = 0;
  Rep(i, 1, n) {
    Rep(c, 0, 25) vis[c] = 0;
    cnt[S[i][0] - 'a'][Has[i][1]]--;
    for (int j = 0; j <= len[i]; j++) {
      Rep(c, 0, 25) if (vis[c]) {
        if (cnt[c].count(Has[i][j]))
          ans += cnt[c][Has[i][j]];
      }
      vis[S[i][j] - 'a'] = 1;
    }
    cnt[S[i][0] - 'a'][Has[i][1]]++;
  }
  cout << ans << "\n";
  return 0;
}