Problem p02589 (C++)

Buggy submission (status: Runtime Error):

#pragma comment(linker, "/STACK: 16777216")

#include <bits/stdc++.h>

#define all(x) (x).begin(), (x).end()
#define allp(x) (x)->begin(), (x)->end()

#define pb push_back

using namespace std;
void dout() { cerr << endl; }
// typedef long long ll;
template <typename Head, typename... Tail> void dout(Head H, Tail... T) {
  cerr << H << ' ';
  dout(T...);
}

#define debug(x) cout << #x " = " << (x) << endl

using ll = long long;
using hll = __int128;
using pii = pair<ll, ll>;
using ld = long double;
using pll = pair<long long, long long>;

template <typename T> void do_uniq(vector<T> vec) {
  sort(all(vec));
  vec.resize(unique(all(vec)) - vec.begin());
}

#ifdef _getchar_nolock
#else
#define _getchar_nolock getchar_unlocked
#endif

template <typename T> void freadT(T &x) {
  x = 0;
  char ch = _getchar_nolock();
  ll sign = 1;

  while (!isdigit(ch)) {
    if (ch == '-')
      sign *= -1;
    ch = _getchar_nolock();
  }

  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = _getchar_nolock();
  }

  x *= sign;
}

int fparse(string s, int start_indx) {
  int x = 0;

  while (isdigit(s[start_indx])) {
    x = x * 10 + s[start_indx] - '0';
    ++start_indx;
  }

  return x;
}

#define solvsh
// #define multi

#ifdef solvsh

const int K = 26;
const int NMAX = 2e5 + 120;

struct vertex {
  int next[K];
  int p;
  char pch;
  int link;
  int go[K];
  int subtree[K];
};

vertex t[NMAX + 1];
int sz;

void init() {
  t[0].p = t[0].link = -1;
  memset(t[0].next, 255, sizeof t[0].next);
  memset(t[0].go, 255, sizeof t[0].go);
  memset(t[0].subtree, 0, sizeof t[0].subtree);
  sz = 1;
}

int cnt_crr[26];

void add_string(const string &s, int indx = 0, int v = 0) {
  if (indx == s.size())
    return;

  char c = s[indx] - 'a';
  if (t[v].next[c] == -1) {
    memset(t[sz].next, 255, sizeof t[sz].next);
    memset(t[sz].go, 255, sizeof t[sz].go);
    memset(t[sz].subtree, 0, sizeof t[sz].subtree);
    t[sz].link = -1;
    t[sz].p = v;
    t[sz].pch = c;
    t[v].next[c] = sz++;
  }

  for (int i = 0; i < 26; ++i) {
    if (cnt_crr[i])
      t[v].subtree[i]++;
  }
  cnt_crr[c]--;
  add_string(s, indx + 1, t[v].next[c]);
}

int go(int v, char c);

int get_link(int v) {
  if (t[v].link == -1)
    if (v == 0 || t[v].p == 0)
      t[v].link = 0;
    else
      t[v].link = go(get_link(t[v].p), t[v].pch);
  return t[v].link;
}

int go(int v, char c) {
  if (t[v].go[c] == -1)
    if (t[v].next[c] != -1)
      t[v].go[c] = t[v].next[c];
    else
      t[v].go[c] = v == 0 ? 0 : go(get_link(v), c);
  return t[v].go[c];
}

void solve() {

  int n;
  cin >> n;

  vector<string> v;
  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    reverse(all(s));
    v.push_back(s);
  }

  init();

  for (auto s : v) {
    for (int i = 0; i < 26; ++i)
      cnt_crr[i] = 0;
    for (auto e : s)
      cnt_crr[e - 'a']++;
    add_string(s);
  }

  ll answr = 0;

  for (auto s : v) {
    int ver = 0;
    for (int j = 0; j < s.size() - 1; ++j) {
      ver = go(ver, s[j] - 'a');
    }

    answr += t[ver].subtree[s.back() - 'a'] - 1;
  }

  cout << answr << "\n";
}

#else

void solve() {}

#endif

clock_t timestamp_start = clock();
void time_calc() {
  cerr << (ld)(clock() - timestamp_start) / CLOCKS_PER_SEC << "\n";
}

void multisolve() {
  //    prec();
  int t;
  cin >> t;

  //    prec();
  //    scanf("%d", &t);

  int i = 1;
  while (t--) {
    //        cout << "Case " << (i ++)<<": \n";
    //        printf("Case %d: \n", i++);

    solve();

    i++;
    //        cout << "\n";
  }
}

#define int int
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
  cout << fixed << setprecision(20);

#ifdef multi
  multisolve();
#else
  solve();
//    gen();
#endif
}

Fixed submission:

#pragma comment(linker, "/STACK: 16777216")

#include <bits/stdc++.h>

#define all(x) (x).begin(), (x).end()
#define allp(x) (x)->begin(), (x)->end()

#define pb push_back

using namespace std;
void dout() { cerr << endl; }
// typedef long long ll;
template <typename Head, typename... Tail> void dout(Head H, Tail... T) {
  cerr << H << ' ';
  dout(T...);
}

#define debug(x) cout << #x " = " << (x) << endl

using ll = long long;
using hll = __int128;
using pii = pair<ll, ll>;
using ld = long double;
using pll = pair<long long, long long>;

template <typename T> void do_uniq(vector<T> vec) {
  sort(all(vec));
  vec.resize(unique(all(vec)) - vec.begin());
}

#ifdef _getchar_nolock
#else
#define _getchar_nolock getchar_unlocked
#endif

template <typename T> void freadT(T &x) {
  x = 0;
  char ch = _getchar_nolock();
  ll sign = 1;

  while (!isdigit(ch)) {
    if (ch == '-')
      sign *= -1;
    ch = _getchar_nolock();
  }

  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = _getchar_nolock();
  }

  x *= sign;
}

int fparse(string s, int start_indx) {
  int x = 0;

  while (isdigit(s[start_indx])) {
    x = x * 10 + s[start_indx] - '0';
    ++start_indx;
  }

  return x;
}

#define solvsh
// #define multi

#ifdef solvsh

const int K = 26;
const int NMAX = 3e6 + 120;

struct vertex {
  int next[K];
  int p;
  char pch;
  int link;
  int go[K];
  int subtree[K];
};

vertex t[NMAX + 1];
int sz;

void init() {
  t[0].p = t[0].link = -1;
  memset(t[0].next, 255, sizeof t[0].next);
  memset(t[0].go, 255, sizeof t[0].go);
  memset(t[0].subtree, 0, sizeof t[0].subtree);
  sz = 1;
}

int cnt_crr[26];

void add_string(const string &s, int indx = 0, int v = 0) {
  if (indx == s.size())
    return;

  char c = s[indx] - 'a';
  if (t[v].next[c] == -1) {
    memset(t[sz].next, 255, sizeof t[sz].next);
    memset(t[sz].go, 255, sizeof t[sz].go);
    memset(t[sz].subtree, 0, sizeof t[sz].subtree);
    t[sz].link = -1;
    t[sz].p = v;
    t[sz].pch = c;
    t[v].next[c] = sz++;
  }

  for (int i = 0; i < 26; ++i) {
    if (cnt_crr[i])
      t[v].subtree[i]++;
  }
  cnt_crr[c]--;
  add_string(s, indx + 1, t[v].next[c]);
}

int go(int v, char c);

int get_link(int v) {
  if (t[v].link == -1)
    if (v == 0 || t[v].p == 0)
      t[v].link = 0;
    else
      t[v].link = go(get_link(t[v].p), t[v].pch);
  return t[v].link;
}

int go(int v, char c) {
  if (t[v].go[c] == -1)
    if (t[v].next[c] != -1)
      t[v].go[c] = t[v].next[c];
    else
      t[v].go[c] = v == 0 ? 0 : go(get_link(v), c);
  return t[v].go[c];
}

void solve() {

  int n;
  cin >> n;

  vector<string> v;
  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    reverse(all(s));
    v.push_back(s);
  }

  init();

  for (auto s : v) {
    for (int i = 0; i < 26; ++i)
      cnt_crr[i] = 0;
    for (auto e : s)
      cnt_crr[e - 'a']++;
    add_string(s);
  }

  ll answr = 0;

  for (auto s : v) {
    int ver = 0;
    for (int j = 0; j < s.size() - 1; ++j) {
      ver = go(ver, s[j] - 'a');
    }

    answr += t[ver].subtree[s.back() - 'a'] - 1;
  }

  cout << answr << "\n";
}

#else

void solve() {}

#endif

clock_t timestamp_start = clock();
void time_calc() {
  cerr << (ld)(clock() - timestamp_start) / CLOCKS_PER_SEC << "\n";
}

void multisolve() {
  //    prec();
  int t;
  cin >> t;

  //    prec();
  //    scanf("%d", &t);

  int i = 1;
  while (t--) {
    //        cout << "Case " << (i ++)<<": \n";
    //        printf("Case %d: \n", i++);

    solve();

    i++;
    //        cout << "\n";
  }
}

#define int int
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
  cout << fixed << setprecision(20);

#ifdef multi
  multisolve();
#else
  solve();
//    gen();
#endif
}