Problem p02589 (C++) — buggy submission, verdict: Runtime Error

// Dmitry _kun_ Sayutin (2020)

#include <bits/stdc++.h>

using std::cerr;
using std::cin;
using std::cout;

using std::array;
using std::map;
using std::queue;
using std::set;
using std::string;
using std::vector;

using std::make_pair;
using std::pair;

using std::get;
using std::make_tuple;
using std::tuple;

using std::abs;
using std::max;
using std::min;
using std::swap;

using std::generate;
using std::max_element;
using std::min_element;
using std::reverse;
using std::sort;
using std::unique;

#ifdef LOCAL
#define LASSERT(X) assert(X)
#else
#define LASSERT(X)                                                             \\
  {}
#endif

template <typename T> T input() {
  T res;
  cin >> res;
  LASSERT(cin);
  return res;
}

template <typename IT> void input_seq(IT b, IT e) {
  std::generate(b, e,
                input<typename std::remove_reference<decltype(*b)>::type>);
}

#define SZ(vec) int((vec).size())
#define ALL(data) data.begin(), data.end()
#define RALL(data) data.rbegin(), data.rend()
#define TYPEMAX(type) std::numeric_limits<type>::max()
#define TYPEMIN(type) std::numeric_limits<type>::min()

struct node_t {
  map<char, node_t *> go;
  array<int, 27> marks;
  bool is_term = false;
};

void traverse(node_t *v, int64_t &ans) {
  array<int, 26> sum;
  std::fill(ALL(sum), 0);

  for (auto &el : v->go) {
    for (int j = 0; j < 26; ++j)
      sum[j] += el.second->marks[j];
  }

  for (auto &el : v->go) {
    traverse(el.second, ans);

    if (el.second->is_term)
      ans += sum[el.first - 'a'] - el.second->marks[el.first - 'a'];
  }

  if (v->is_term) {
    ans += v->marks[26] - 1;
  }
}

int main() {
  std::iostream::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);

  // code here
  node_t *root = new node_t();

  int n = input<int>();
  int64_t ans = 0;

  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    reverse(ALL(s));

    vector<node_t *> seq = {root};

    node_t *cur = root;
    for (char ch : s) {
      if (not cur->go[ch])
        cur->go[ch] = new node_t();

      cur = cur->go[ch];
      seq.push_back(cur);
    }

    cur->is_term = 1;
    cur->marks[26] += 1;

    int markset = 1 << 26;
    for (int i = SZ(s) - 1; i >= 0; --i) {
      markset |= (1 << (s[i] - 'a'));

      for (int j = 0; j <= 26; ++j)
        if (markset & (1 << j))
          seq[i]->marks[j] += 1;
    }
  }

  traverse(root, ans);
  cout << ans << "\\n";

  return 0;
}


Error: 0

Fixed submission:

// Dmitry _kun_ Sayutin (2020)

#include <bits/stdc++.h>

using std::cerr;
using std::cin;
using std::cout;

using std::array;
using std::map;
using std::queue;
using std::set;
using std::string;
using std::vector;

using std::make_pair;
using std::pair;

using std::get;
using std::make_tuple;
using std::tuple;

using std::abs;
using std::max;
using std::min;
using std::swap;

using std::generate;
using std::max_element;
using std::min_element;
using std::reverse;
using std::sort;
using std::unique;

#ifdef LOCAL
#define LASSERT(X) assert(X)
#else
#define LASSERT(X)                                                             \\
  {}
#endif

template <typename T> T input() {
  T res;
  cin >> res;
  LASSERT(cin);
  return res;
}

template <typename IT> void input_seq(IT b, IT e) {
  std::generate(b, e,
                input<typename std::remove_reference<decltype(*b)>::type>);
}

#define SZ(vec) int((vec).size())
#define ALL(data) data.begin(), data.end()
#define RALL(data) data.rbegin(), data.rend()
#define TYPEMAX(type) std::numeric_limits<type>::max()
#define TYPEMIN(type) std::numeric_limits<type>::min()

struct node_t {
  map<char, node_t *> go;
  bool is_term = false;
};

array<int, 27> traverse(node_t *v, string &s, int64_t &ans) {
  array<int, 27> cur;
  std::fill(ALL(cur), 0);

  vector<char> let;
  vector<node_t *> go;
  vector<array<int, 27>> data;

  for (auto &el : v->go) {
    let.push_back(el.first - 'a');
    go.push_back(el.second);

    s += el.first;
    array<int, 27> res = traverse(el.second, s, ans);
    s.pop_back();
    data.push_back(res);

    for (int i = 0; i <= 26; ++i)
      cur[i] += res[i];
  }

  for (int i = 0; i < SZ(go); ++i) {
    if (go[i]->is_term)
      ans += cur[let[i]] - data[i][let[i]];
  }

  if (v->is_term) {
    ans += cur[26];
    cur[26] += 1;

    int letset = 0;
    for (char ch : s)
      letset |= (1 << (ch - 'a'));

    for (int i = 0; i < 26; ++i)
      if (letset & (1 << i))
        cur[i] += 1;
  }

  return cur;
}

int main() {
  std::iostream::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);

  // code here
  node_t *root = new node_t();

  int n = input<int>();
  int64_t ans = 0;

  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    reverse(ALL(s));

    node_t *cur = root;
    for (char ch : s) {
      if (not cur->go[ch])
        cur->go[ch] = new node_t();

      cur = cur->go[ch];
    }

    cur->is_term = 1;
  }

  string cur;
  traverse(root, cur, ans);
  cout << ans << "\\n";

  return 0;
}