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

#define _CRT_SECURE_NO_DEPRECATE
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
#include "bits/stdc++.h"
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
using namespace std;
// using namespace __gnu_pbds;
#define SYNC                                                                   \\
  std::ios_base::sync_with_stdio(0);                                           \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define FRE                                                                    \\
  freopen("input.txt", "r", stdin);                                            \\
  freopen("output.txt", "w", stdout);
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
//              tree_order_statistics_node_update>
//     ost;
#define rep(i, l, r) for (int i = (l); i < (r); i++)
#define here cout << " Hey!!\\n";
#define pb push_back
#define F first
#define S second
#define all(v) (v).begin(), (v).end()
#define sz(a) (int)((a).size())
#define sq(x) ((x) * (x))
template <typename T> void etch(T V) {
  for (auto x : V)
    cout << x << ' ';
  cout << '\\n';
}
vector<string> vec_splitter(string s) {
  s += ',';
  vector<string> res;
  while (!s.empty()) {
    res.push_back(s.substr(0, s.find(',')));
    s = s.substr(s.find(',') + 1);
  }
  return res;
}
void debug_out(vector<string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
  cerr << endl;
}
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
  if (idx > 0)
    cerr << ", ";
  else
    cerr << "Line(" << LINE_NUM << ") ";
  stringstream ss;
  ss << H;
  cerr << args[idx] << " = " << ss.str();
  debug_out(args, idx + 1, LINE_NUM, T...);
}
#ifndef ONLINE_JUDGE
#define debug(...)                                                             \\
  debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif
const int MOD = 1e9 + 7;
const int MOD1 = 998244353;
const int N = 2e5 + 5;
const ld EPS = 1e-12;

struct node {
  long long dp[26];
  node *nxt[26];
  node() {
    rep(i, 0, 26) {
      dp[i] = 0;
      nxt[i] = NULL;
    }
  }
};
node *root;
string s;
map<string, long long> fre;
vector<string> a;
bool comp(string &x, string &y) { return sz(x) > sz(y); }
int32_t main() {
  SYNC int n;
  cin >> n;
  root = new node;
  long long ans = 0;
  a.resize(n);
  rep(i, 0, n) cin >> a[i];
  sort(all(a), comp);
  vi magic(26, 0);
  rep(i, 0, n) {
    s = a[i];
    reverse(all(s));
    if (sz(s) == 1)
      fre[s]++;
    else {
      node *cur = root;
      int ok = true;
      for (int j = 0; j < sz(s) - 1; j++) {
        int now = s[j] - 'a';
        if (cur->nxt[now] == NULL) {
          ok = false;
          break;
        } else {
          cur = cur->nxt[now];
        }
      }
      if (ok) {
        ans += cur->dp[int(s[sz(s) - 1] - 'a')];
        debug(a[i], ans, s[sz(s) - 1]);
      }
      bool cum[sz(s)][26];
      memset(cum, false, sizeof cum);
      cum[sz(s) - 1][int(s.back() - 'a')] = true;
      for (int j = sz(s) - 2; j >= 0; j--) {
        rep(k, 0, 26) cum[j][k] = cum[j + 1][k];
        cum[j][s[j] - 'a'] = true;
      }
      rep(k, 0, 26) {
        if (cum[0][k])
          magic[k]++;
      }
      // if (i == 1) {
      //     debug(cum[0][0], cum[0][1], cum[1][0], cum[1][1]);
      // }
      cur = root;
      for (int j = 0; j < sz(s); j++) {
        int now = s[j] - 'a';
        if (1) {
          rep(k, 0, 26) {
            if (cum[j][k]) {
              cur->dp[k]++;
            }
          }
        }
        if (cur->nxt[now] != NULL) {
          cur = cur->nxt[now];
        } else {
          cur->nxt[now] = new node;
          cur = cur->nxt[now];
        }
      }
    }
  }
  for (auto it : fre) {
    ans += (long long)((long long)it.S * (it.S - 1)) / 2;
    ans += (long long)((long long)magic[it.F[0] - 'a'] * it.S);
  }
  cout << ans;
  return 0;
}

Error: TLE

Fixed submission:

#define _CRT_SECURE_NO_DEPRECATE
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
#include "bits/stdc++.h"
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
using namespace std;
// using namespace __gnu_pbds;
#define int long long int
#define SYNC                                                                   \\
  std::ios_base::sync_with_stdio(0);                                           \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define FRE                                                                    \\
  freopen("input.txt", "r", stdin);                                            \\
  freopen("output.txt", "w", stdout);
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
// typedef tree<int, null_type, less<int>, rb_tree_tag,
//              tree_order_statistics_node_update>
//     ost;
#define rep(i, l, r) for (int i = (l); i < (r); i++)
#define here cout << " Hey!!\\n";
#define pb push_back
#define F first
#define S second
#define all(v) (v).begin(), (v).end()
#define sz(a) (int)((a).size())
#define sq(x) ((x) * (x))
template <typename T> void etch(T V) {
  for (auto x : V)
    cout << x << ' ';
  cout << '\\n';
}
vector<string> vec_splitter(string s) {
  s += ',';
  vector<string> res;
  while (!s.empty()) {
    res.push_back(s.substr(0, s.find(',')));
    s = s.substr(s.find(',') + 1);
  }
  return res;
}
void debug_out(vector<string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
  cerr << endl;
}
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
  if (idx > 0)
    cerr << ", ";
  else
    cerr << "Line(" << LINE_NUM << ") ";
  stringstream ss;
  ss << H;
  cerr << args[idx] << " = " << ss.str();
  debug_out(args, idx + 1, LINE_NUM, T...);
}
#ifndef ONLINE_JUDGE
#define debug(...)                                                             \\
  debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif
const int MOD = 1e9 + 7;
const int MOD1 = 998244353;
const int N = 2e5 + 5;
const int INF = 1000111000111000111LL;
const ld EPS = 1e-12;
const ld PI = 3.141592653589793116;
vector<string> v;
bool ok(string a, string b) {
  if (sz(a) < sz(b))
    return false;
  int j = sz(a) - 1, i = sz(b) - 1;
  int skip = 0;
  while (i >= 0 && j >= 0 && a[j] == b[i]) {
    j--;
    i--;
  }
  if (i < 0)
    return true;
  if (i > 0)
    return false;
  rep(k, 0, j + 1) {
    if (a[k] == b[0])
      return true;
  }
  return false;
}
int32_t main() {
  SYNC int n;
  cin >> n;
  v.resize(n);
  rep(i, 0, n) cin >> v[i];
  int ans = 0;
  rep(i, 0, n) {
    rep(j, i + 1, n) {
      if (ok(v[i], v[j]) || ok(v[j], v[i])) {
        ans++;
      }
    }
  }
  cout << ans;
  return 0;
}