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

#include <bits/stdc++.h>
#define Rint register int
#define MP make_pair
#define fi first
#define se second
#define PB push_back
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;
const int N = 200003, M = 1000003, mod = 1004535809, X = 23333;
template <typename T> void read(T &x) {
  int ch = getchar();
  x = 0;
  bool f = false;
  for (; ch < '0' || ch > '9'; ch = getchar())
    f |= ch == '-';
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  if (f)
    x = -x;
}
void qmo(int &x) { x += (x >> 31) & mod; }
int ksm(int a, int b) {
  int res = 1;
  for (; b; b >>= 1, a = (LL)a * a % mod)
    if (b & 1)
      res = (LL)res * a % mod;
  return res;
}
template <typename T> inline bool chmax(T &a, const T &b) {
  if (a < b)
    return a = b, 1;
  return 0;
}
template <typename T> inline bool chmin(T &a, const T &b) {
  if (a > b)
    return a = b, 1;
  return 0;
}
int n, len[N], po[M], pre[M], ap[26][N], ll, cnt[N];
char str[M];
LL ans, val[N];
unordered_map<LL, int> sd;
int main() {
#ifdef NTFOrz
  freopen("a.in", "r", stdin);
#endif
  read(n);
  po[0] = 1;
  for (Rint i = 1; i < M; ++i)
    po[i] = (LL)po[i - 1] * X % mod;
  memset(ap, 0x3f, sizeof ap);
  for (Rint i = 1; i <= n; ++i) {
    scanf("%s", str + len[i - 1]);
    len[i] = len[i - 1] + strlen(str + len[i - 1]);
    ap[str[len[i - 1]] - 'a'][i] = len[i - 1];
    pre[len[i - 1]] = str[len[i - 1]];
    for (Rint j = len[i - 1] + 1; j < len[i]; ++j) {
      if (ap[str[j] - 'a'][i] > M)
        ap[str[j] - 'a'][i] = j;
      pre[j] = ((LL)pre[j - 1] * X + str[j]) % mod;
    }
  }
  for (Rint i = 1; i <= n; ++i)
    val[i] = (len[i] - len[i - 1] - 1) * 26ll * mod +
             (LL)(str[len[i - 1]] - 'a') * mod +
             (pre[len[i] - 1] -
              (LL)pre[len[i - 1]] * po[len[i] - len[i - 1] - 1] % mod + mod) %
                 mod;
  sort(val + 1, val + n + 1);
  ll = unique(val + 1, val + n + 1) - val;
  for (Rint i = 1; i < ll; ++i)
    cnt[i] = 1, sd[val[i]] = i;
  for (Rint i = ll; i <= n; ++i)
    ++cnt[lower_bound(val + 1, val + ll, val[i]) - val];
  for (Rint i = 1; i <= n; ++i)
    for (Rint j = len[i - 1]; j < len[i]; ++j)
      for (Rint k = 0; k < 26; ++k)
        if (ap[k][i] <= j) {
          LL value =
              (len[i] - j - 1) * 26ll * mod + (LL)k * mod +
              (pre[len[i] - 1] - (LL)pre[j] * po[len[i] - 1 - j] % mod + mod) %
                  mod;
          if (sd.count(value))
            ans += cnt[sd[value]];
        }
  printf("%lld\\n", ans - n);
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define Rint register int
#define MP make_pair
#define fi first
#define se second
#define PB push_back
using namespace std;
typedef long long LL;
typedef pair<int, LL> pii;
const int N = 200003, M = 1000003, mod = 1004535809, X = 23333;
template <typename T> void read(T &x) {
  int ch = getchar();
  x = 0;
  bool f = false;
  for (; ch < '0' || ch > '9'; ch = getchar())
    f |= ch == '-';
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  if (f)
    x = -x;
}
void qmo(int &x) { x += (x >> 31) & mod; }
int ksm(int a, int b) {
  int res = 1;
  for (; b; b >>= 1, a = (LL)a * a % mod)
    if (b & 1)
      res = (LL)res * a % mod;
  return res;
}
template <typename T> inline bool chmax(T &a, const T &b) {
  if (a < b)
    return a = b, 1;
  return 0;
}
template <typename T> inline bool chmin(T &a, const T &b) {
  if (a > b)
    return a = b, 1;
  return 0;
}
int n, len[N], po[M], pre[M], ap[26][N];
char str[M];
LL ans;
map<pii, int> sd;
int main() {
  read(n);
  po[0] = 1;
  for (Rint i = 1; i < M; ++i)
    po[i] = (LL)po[i - 1] * X % mod;
  memset(ap, 0x3f, sizeof ap);
  for (Rint i = 1; i <= n; ++i) {
    scanf("%s", str + len[i - 1]);
    len[i] = len[i - 1] + strlen(str + len[i - 1]);
    ap[str[len[i - 1]] - 'a'][i] = len[i - 1];
    pre[len[i - 1]] = str[len[i - 1]];
    for (Rint j = len[i - 1] + 1; j < len[i]; ++j) {
      if (ap[str[j] - 'a'][i] > M)
        ap[str[j] - 'a'][i] = j;
      pre[j] = ((LL)pre[j - 1] * X + str[j]) % mod;
    }
  }
  for (Rint i = 1; i <= n; ++i)
    ++sd[MP(len[i] - len[i - 1] - 1,
            (LL)(str[len[i - 1]] - 'a') * mod +
                (pre[len[i] - 1] -
                 (LL)pre[len[i - 1]] * po[len[i] - len[i - 1] - 1] % mod +
                 mod) %
                    mod)];
  for (Rint i = 1; i <= n; ++i)
    for (Rint j = len[i - 1]; j < len[i]; ++j)
      for (Rint k = 0; k < 26; ++k)
        if (ap[k][i] <= j)
          ans += sd[MP(len[i] - j - 1,
                       (LL)k * mod +
                           (pre[len[i] - 1] -
                            (LL)pre[j] * po[len[i] - 1 - j] % mod + mod) %
                               mod)];
  printf("%lld\\n", ans - n);
}