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

#include <bits/stdc++.h>
// #include<tr1::unordered_map>
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
#define pb push_back
#define fi first
#define se second
#define io std::ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int P = 1e9 + 7, INF = 0x3f3f3f3f;
const int maxn = 1e6 + 50;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qpow(ll a, ll n) {
  ll r = 1 % P;
  for (a %= P; n; a = a * a % P, n >>= 1)
    if (n & 1)
      r = r * a % P;
  return r;
}
struct node {
  int a[26];
  int b[26];
  // int num;
};
node tree[maxn];
int pre[maxn];
int cnt;
int ans;
void add(string x) {
  int cur = 0;
  int flag = 0;
  for (int i = 0; i < x.size(); i++) {
    int now = x[i] - 'a';
    if (!tree[cur].a[now]) {
      tree[cur].a[now] = ++cnt;
      pre[cnt] = cur;
    }
    cur = tree[cur].a[now];
    // tree[cur].num++;
  }
  int len = x.size() - 1;
  int cntt[26];
  memset(cntt, 0, sizeof(cntt));
  while (cur) {
    int pe = pre[cur];
    int now = x[len] - 'a';
    if (!cntt[now]) {
      cntt[now]++;
    }
    for (int i = 0; i < 26; i++) {
      if (cntt[i])
        tree[pe].b[i]++;
    }
    cur = pre[cur];
    len--;
  }
}
string a[maxn];
bool cmp(string x, string y) { return x.size() > y.size(); }
int main() {
  io;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  sort(a + 1, a + 1 + n, cmp);
  for (int i = 1; i <= n; i++) {
    reverse(a[i].begin(), a[i].end());
    int cur = 0;
    int flag = 0;
    for (int j = 0; j < a[i].size() - 1; j++) {
      char x = a[i][j];
      int now = x - 'a';
      if (!tree[cur].a[now]) {
        flag = 1;
        break;
      }
      cur = tree[cur].a[now];
    }
    if (flag) {
      add(a[i]);
      continue;
    }
    int last = a[i].back() - 'a';
    ans += tree[cur].b[last];
    add(a[i]);
  }
  cout << ans << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
// #include<tr1::unordered_map>
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
#define pb push_back
#define fi first
#define se second
#define io std::ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int P = 1e9 + 7, INF = 0x3f3f3f3f;
const int maxn = 1e6 + 50;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qpow(ll a, ll n) {
  ll r = 1 % P;
  for (a %= P; n; a = a * a % P, n >>= 1)
    if (n & 1)
      r = r * a % P;
  return r;
}
struct node {
  int a[26];
  int b[26];
  // int num;
};
node tree[maxn];
int pre[maxn];
int cnt;
int ans;
void add(string x) {
  int cur = 0;
  int flag = 0;
  for (int i = 0; i < x.size(); i++) {
    int now = x[i] - 'a';
    if (!tree[cur].a[now]) {
      tree[cur].a[now] = ++cnt;
      pre[cnt] = cur;
    }
    cur = tree[cur].a[now];
    // tree[cur].num++;
  }
  int len = x.size() - 1;
  while (cur) {
    int pe = pre[cur];
    int cntt[26];
    memset(cntt, 0, sizeof(cntt));
    for (int i = x.size() - 1; i >= len; i--) {
      int now = x[i] - 'a';
      if (!cntt[now]) {
        tree[pe].b[now]++;
        cntt[now]++;
      }
    }
    cur = pre[cur];
    len--;
  }
}
string a[maxn];
bool cmp(string x, string y) { return x.size() > y.size(); }
int main() {
  io;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  sort(a + 1, a + 1 + n, cmp);
  for (int i = 1; i <= n; i++) {
    reverse(a[i].begin(), a[i].end());
    int cur = 0;
    int flag = 0;
    for (int j = 0; j < a[i].size() - 1; j++) {
      char x = a[i][j];
      int now = x - 'a';
      if (!tree[cur].a[now]) {
        flag = 1;
        break;
      }
      cur = tree[cur].a[now];
    }
    if (flag) {
      add(a[i]);
      continue;
    }
    int last = a[i].back() - 'a';
    ans += tree[cur].b[last];
    add(a[i]);
  }
  cout << ans << endl;
}