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

#include <bits/stdc++.h>

#define endl "\\n"
#define EPS 1E-9
#define PI acos(-1)
#define sq(x) ((x) * (x))
#define ln length
#define F first
#define S second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define PF push_front
#define PPB pop_back
#define PPF pop_front
#define ODD(x) (((x)&1LL) ? (1) : (0))
#define all(v) (v).begin(), (v).end()
#define UNIQUE(v) (v).erase(unique(all(v)), (v).end())
#define f0(i, n) for (i = (0); i < (n); ++i)
#define f1(i, n) for (i = (1); i <= (n); ++i)
#define fab(i, a, b) for (i = (a); i <= (b); ++i)
#define fr(i, b, a) for (i = (b); i >= (a); --i)
#define mark(x) (marked[(x) >> 6] |= (1L << (((x) % 64) >> 1)))
#define on(x) (marked[(x) >> 6] & (1L << (((x) % 64) >> 1)))

using namespace std;

/*
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,
    tree_order_statistics_node_update> indexed_set;
//*/
typedef long long int ll;
#define int long int
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
// typedef tuple<ll, ll, ll> tll;

inline bool compare(ll x, ll y) { return x > y; }
template <typename T> T binaryExpo(T n, T p) {
  if (p == 0) {
    return 1LL;
  }
  if (p & 1) {
    return n * binaryExpo(n, p - 1);
  }
  T ret = binaryExpo(n, p / 2);
  return ret * ret;
}
template <typename T> T bigMod(T n, T p, T m) {
  if (p == 0) {
    return 1LL % m;
  }
  if (p & 1) {
    return (n % m * bigMod(n, p - 1, m)) % m;
  }
  T ret = bigMod(n, p / 2, m) % m;
  return (ret * ret) % m;
}
template <typename T> T modInv(T n, T m) { return bigMod(n, m - 2, m); }

const ll maxN = 2e5 + 10;
const ll maxB = 320;
const ll INF = 9187201950435737471; // const int  INF =  2139062143;
const ll maxA = 1e6 + 10;
const ll MOD = 1e9 + 7;
const ll _INF = -9187201950435737472; // const int _INF = -2139062144;

// int dx[8] = { 0,   1,  1,  1,  0,  -1, -1, -1};
// int dy[8] = {-1,  -1,  0,  1,  1,   1,  0, -1};
//               N   NE   E  SE   S   SW   W   NW
// int dx[4] = { 0,       1,      0,      -1    };
// int dy[4] = {-1,       0,      1,       0    };
// int row, column;

int marked[ //(maxA>>6) // only for odd numbers
    +2];
vector<ll> prime;

//* function prototypes
void sieve(ll n);
bool is_prime(ll num);
//*/

#ifdef DEBUG
#endif // DEBUG
#ifndef ONLINE_JUDGE
#endif // ONLINE_JUDGE
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
map<ll, string> res = {{0, "No"}, {1, "Yes"}};
string s[maxN];

struct node {
  map<char, node *> path;
  set<int> end_of;
  node() {}
};
unordered_map<char, ll> mp;

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout.precision(15);
  cout << fixed;
#ifndef ONLINE_JUDGE
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
#endif // ONLINE_JUDGE

  // sieve(maxA);
  ll number_of_test_cases = 1, test_case;
  // cin >> number_of_test_cases;
  for (test_case = 1; test_case <= number_of_test_cases; test_case++) {
    // cout << "Test #" << test_case << ": ";
    // cout << "Case "  << test_case << ": ";
    ll i, j, k, m, n, query_type, q;

    cin >> n;
    f0(i, n) cin >> s[i];
    f0(i, n) { reverse(all(s[i])); }

    node *root = new node;
    node *curr;

    f0(i, n) {
      curr = root;
      f0(j, s[i].length() - 1) {
        if (curr->path.count(s[i][j]) == 0) {
          curr->path[s[i][j]] = new node;
        }
        curr = curr->path[s[i][j]];
      }
      curr->end_of.insert(i);
    }
    ll ans = 0;
    f0(i, n) {
      curr = root;
      mp.clear();
      for (auto c : s[i])
        mp[c]++;
      for (j = 0; j < s[i].length(); j++) {
        for (auto e : curr->end_of) {
          if (e == i)
            continue;
          if (mp[s[e].back()] > 0) {
            ans++;
          }
        }
        curr = curr->path[s[i][j]];
        mp[s[i][j]]--;
      }
    }
    cout << ans << endl;
  }

#ifndef ONLINE_JUDGE
  cerr << "\\n........................   execution time : "
       << 1.0 * clock() / CLOCKS_PER_SEC << " s";
#endif // ONLINE_JUDGE
  return 0;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

bool is_prime(ll num) {
  return (num > 1 && (num == 2 || (ODD(num) && !on(num))));
}
void sieve(ll n) {
  ll i, j;
  mark(1);
  for (i = 3; i * i <= n; i += 2) {
    if (!on(i)) {
      for (j = i * i; j <= n; j += i + i)
        mark(j);
    }
  }
  prime.clear();
  prime.push_back(2);
  for (i = 3; i <= n; i += 2) {
    if (is_prime(i))
      prime.push_back(i);
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define endl "\\n"
#define EPS 1E-9
#define PI acos(-1)
#define sq(x) ((x) * (x))
#define ln length
#define F first
#define S second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define PF push_front
#define PPB pop_back
#define PPF pop_front
#define ODD(x) (((x)&1LL) ? (1) : (0))
#define all(v) (v).begin(), (v).end()
#define UNIQUE(v) (v).erase(unique(all(v)), (v).end())
#define f0(i, n) for (i = (0); i < (n); ++i)
#define f1(i, n) for (i = (1); i <= (n); ++i)
#define fab(i, a, b) for (i = (a); i <= (b); ++i)
#define fr(i, b, a) for (i = (b); i >= (a); --i)
#define mark(x) (marked[(x) >> 6] |= (1L << (((x) % 64) >> 1)))
#define on(x) (marked[(x) >> 6] & (1L << (((x) % 64) >> 1)))

using namespace std;

/*
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,
    tree_order_statistics_node_update> indexed_set;
//*/
typedef long long int ll;
#define int long int
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
// typedef tuple<ll, ll, ll> tll;

inline bool compare(ll x, ll y) { return x > y; }
template <typename T> T binaryExpo(T n, T p) {
  if (p == 0) {
    return 1LL;
  }
  if (p & 1) {
    return n * binaryExpo(n, p - 1);
  }
  T ret = binaryExpo(n, p / 2);
  return ret * ret;
}
template <typename T> T bigMod(T n, T p, T m) {
  if (p == 0) {
    return 1LL % m;
  }
  if (p & 1) {
    return (n % m * bigMod(n, p - 1, m)) % m;
  }
  T ret = bigMod(n, p / 2, m) % m;
  return (ret * ret) % m;
}
template <typename T> T modInv(T n, T m) { return bigMod(n, m - 2, m); }

const ll maxN = 2e5 + 10;
const ll maxB = 320;
const ll INF = 9187201950435737471; // const int  INF =  2139062143;
const ll maxA = 1e6 + 10;
const ll MOD = 1e9 + 7;
const ll _INF = -9187201950435737472; // const int _INF = -2139062144;

// int dx[8] = { 0,   1,  1,  1,  0,  -1, -1, -1};
// int dy[8] = {-1,  -1,  0,  1,  1,   1,  0, -1};
//               N   NE   E  SE   S   SW   W   NW
// int dx[4] = { 0,       1,      0,      -1    };
// int dy[4] = {-1,       0,      1,       0    };
// int row, column;

int marked[ //(maxA>>6) // only for odd numbers
    +2];
vector<ll> prime;

//* function prototypes
void sieve(ll n);
bool is_prime(ll num);
//*/

#ifdef DEBUG
#endif // DEBUG
#ifndef ONLINE_JUDGE
#endif // ONLINE_JUDGE
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
map<ll, string> res = {{0, "No"}, {1, "Yes"}};
string s[maxN];

struct node {
  map<char, node *> path;
  set<int> end_of;
  node() {}
};
map<char, ll> mp;

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout.precision(15);
  cout << fixed;
#ifndef ONLINE_JUDGE
  // freopen("input.txt", "r", stdin);
  // freopen("output.txt", "w", stdout);
#endif // ONLINE_JUDGE

  // sieve(maxA);
  ll number_of_test_cases = 1, test_case;
  // cin >> number_of_test_cases;
  for (test_case = 1; test_case <= number_of_test_cases; test_case++) {
    // cout << "Test #" << test_case << ": ";
    // cout << "Case "  << test_case << ": ";
    ll i, j, k, m, n, query_type, q;

    cin >> n;
    f0(i, n) cin >> s[i];
    f0(i, n) { reverse(all(s[i])); }

    node *root = new node;
    node *curr;

    f0(i, n) {
      curr = root;
      f0(j, s[i].length() - 1) {
        if (curr->path.count(s[i][j]) == 0) {
          curr->path[s[i][j]] = new node;
        }
        curr = curr->path[s[i][j]];
      }
      curr->end_of.insert(i);
    }
    set<pll> ans;
    f0(i, n) {
      curr = root;
      mp.clear();
      for (auto c : s[i])
        mp[c]++;
      for (j = 0; j < s[i].length(); j++) {
        for (auto e : curr->end_of) {
          if (e == i)
            continue;
          if (mp[s[e].back()] > 0) {
            ans.insert(MP(e, i));
            ans.insert(MP(i, e));
          }
        }
        curr = curr->path[s[i][j]];
        mp[s[i][j]]--;
      }
    }
    assert(ans.size() % 2 == 0);
    cout << ans.size() / 2 << endl;
  }

#ifndef ONLINE_JUDGE
  cerr << "\\n........................   execution time : "
       << 1.0 * clock() / CLOCKS_PER_SEC << " s";
#endif // ONLINE_JUDGE
  return 0;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###################################################################################################################
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

bool is_prime(ll num) {
  return (num > 1 && (num == 2 || (ODD(num) && !on(num))));
}
void sieve(ll n) {
  ll i, j;
  mark(1);
  for (i = 3; i * i <= n; i += 2) {
    if (!on(i)) {
      for (j = i * i; j <= n; j += i + i)
        mark(j);
    }
  }
  prime.clear();
  prime.push_back(2);
  for (i = 3; i <= n; i += 2) {
    if (is_prime(i))
      prime.push_back(i);
  }
}