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

//{{{
#include <algorithm>
#include <cmath>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <sys/time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include "rprint2.hpp"
#else
#define FUNC(name)                                                             \\
  template <ostream &out = cout, class... T> void name(T &&...) {}
FUNC(printde)
FUNC(printdbe) FUNC(printdwe) FUNC(printdu) FUNC(printe) FUNC(printe0);
#endif
template <template <class T, class = std::allocator<T>> class V, class E>
istream &operator>>(istream &in, V<E> &v) {
  for (auto &e : v) {
    in >> e;
  }
  return in;
}
//}}}

struct Node {
  char chr;
  Node *par = nullptr;
  map<char, pair<int, Node *>> dests;
  int nums[27] = {};
  bool leaf = false;
  Node() {}
  Node(Node *n) : Node() { par = n; }
  Node *make(string &str, vector<int> &azs, int idx = 0) {
    chr = str[idx];
    azs[chr - 'a']--;
    for (int i = 0; i < 27; i++) {
      nums[i] += azs[i] > 0;
    }
    printde(chr, nums);
    if ((int)str.size() == idx + 1) {
      leaf = true;
      return this;
    }
    char next = str[idx + 1];
    if (dests.count(next)) {
      dests[next].first++;
    } else {
      Node *n = new Node(this);
      dests[next] = {1, n};
    }
    return dests[next].second->make(str, azs, idx + 1);
  }

  ll calc() {
    ll ret = 0;
    printde(chr, dests.size());
    if (leaf) {
      // par->calc2(chr);
      ret = par->nums[chr - 'a'] - 1;
      printde(chr, ret, par->chr, par->nums[chr - 'a']);
      // ret = par->dests[chr].first - 1;
      // printde(chr, ret, par->dests[chr].first);
    }
    for (auto &dest : dests) {
      ret += dest.second.second->calc();
    }
    return ret;
  }
};

struct Trie {
  struct Node {
    char ch;
    map<char, int> dests;
    int parentIdx;
    int nums[27] = {};
    bool leaf = false;
    bool isRoot() { return !ch; }
  };
  vector<Node> nodes;
  void add(string &s, vector<int> &azs, int sidx = -1, int nidx = 0,
           int pidx = -1) {
    if (nidx >= (int)nodes.size()) {
      nodes.push_back({});
    }
    auto &dests = nodes[nidx].dests;
    nodes[nidx].ch = sidx >= 0 ? s[sidx] : 0;
    nodes[nidx].parentIdx = pidx;

    if (!nodes[nidx].isRoot()) {
      azs[nodes[nidx].ch - 'a']--;
      for (int i = 0; i < 27; i++) {
        nodes[nidx].nums[i] += azs[i] > 0;
      }
    }
    // printde(nodes[nidx].ch, nodes[nidx].nums);

    if (sidx + 1 == (int)s.size()) {
      nodes[nidx].leaf = true;
      return;
    }
    char next = s[sidx + 1];
    if (!dests.count(next)) {
      dests[next] = nodes.size();
      add(s, azs, sidx + 1, nodes.size(), nidx);
    } else {
      add(s, azs, sidx + 1, dests[next], nidx);
    }
    printde(nodes[nidx].ch);
    // printde(nodes[nidx].ch, nodes[nidx].dests);
  }

  ll calc(int nidx = 0) {
    ll ret = 0;
    printde(nodes[nidx].ch, nodes[nidx].dests);
    if (nodes[nidx].leaf) {
      ret = nodes[nodes[nidx].parentIdx].nums[nodes[nidx].ch - 'a'] - 1;
      // printde(nodes[nidx].ch, ret, nodes[nodes[nidx].parentIdx].ch,
      // nodes[nodes[nidx].parentIdx].nums[nodes[nidx].ch - 'a']);
    }
    for (auto &dest : nodes[nidx].dests) {
      ret += calc(dest.second);
    }
    return ret;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  // Node root;
  Trie root;
  root.nodes.reserve(100000);
  vector<int> azs(27);
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    s += 'a' + 26;
    reverse(s.begin(), s.end());
    azs.assign(27, 0);
    for (auto &c : s) {
      azs[c - 'a']++;
    }
    // root.make(s, azs);
    root.add(s, azs);
  }
  cout << root.calc() << '\\n';
}
/*
a
ba
abc
dabc
eabdc
*/


Error: 0

Fixed submission:

//{{{
#include <algorithm>
#include <cmath>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <sys/time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include "rprint2.hpp"
#else
#define FUNC(name)                                                             \\
  template <ostream &out = cout, class... T> void name(T &&...) {}
FUNC(printde)
FUNC(printdbe) FUNC(printdwe) FUNC(printdu) FUNC(printe) FUNC(printe0);
#endif
template <template <class T, class = std::allocator<T>> class V, class E>
istream &operator>>(istream &in, V<E> &v) {
  for (auto &e : v) {
    in >> e;
  }
  return in;
}
//}}}

struct Node {
  char chr;
  Node *par = nullptr;
  map<char, pair<int, Node *>> dests;
  int nums[27] = {};
  bool leaf = false;
  Node() {}
  Node(Node *n) : Node() { par = n; }
  Node *make(string &str, vector<int> &azs, int idx = 0) {
    chr = str[idx];
    azs[chr - 'a']--;
    for (int i = 0; i < 27; i++) {
      nums[i] += azs[i] > 0;
    }
    printde(chr, nums);
    if ((int)str.size() == idx + 1) {
      leaf = true;
      return this;
    }
    char next = str[idx + 1];
    if (dests.count(next)) {
      dests[next].first++;
    } else {
      Node *n = new Node(this);
      dests[next] = {1, n};
    }
    return dests[next].second->make(str, azs, idx + 1);
  }

  ll calc() {
    ll ret = 0;
    printde(chr, dests.size());
    if (leaf) {
      // par->calc2(chr);
      ret = par->nums[chr - 'a'] - 1;
      printde(chr, ret, par->chr, par->nums[chr - 'a']);
      // ret = par->dests[chr].first - 1;
      // printde(chr, ret, par->dests[chr].first);
    }
    for (auto &dest : dests) {
      ret += dest.second.second->calc();
    }
    return ret;
  }
};

struct Trie {
  struct Node {
    char ch;
    // map<char, int> dests;
    // unordered_map<char, int> dests;
    int dests[27] = {};
    int parentIdx;
    int nums[27] = {};
    bool leaf = false;
    bool isRoot() { return !ch; }
  };
  vector<Node> nodes;
  void add(string &s, vector<int> &azs, int sidx = -1, int nidx = 0,
           int pidx = -1) {
    if (nidx >= (int)nodes.size()) {
      nodes.push_back({});
    }
    auto &dests = nodes[nidx].dests;
    nodes[nidx].ch = sidx >= 0 ? s[sidx] : 0;
    nodes[nidx].parentIdx = pidx;

    if (!nodes[nidx].isRoot()) {
      azs[nodes[nidx].ch - 'a']--;
      for (int i = 0; i < 27; i++) {
        nodes[nidx].nums[i] += azs[i] > 0;
      }
    }
    printde(nodes[nidx].ch, nodes[nidx].nums);

    if (sidx + 1 == (int)s.size()) {
      nodes[nidx].leaf = true;
      return;
    }
    // int next = s[sidx + 1];
    // if(!dests.count(next)){
    int next = s[sidx + 1] - 'a';
    if (!dests[next]) {
      dests[next] = nodes.size();
      add(s, azs, sidx + 1, nodes.size(), nidx);
    } else {
      add(s, azs, sidx + 1, dests[next], nidx);
    }
    // printde(nodes[nidx].ch);
    // printde(nodes[nidx].ch, nodes[nidx].dests);
  }

  ll calc(int nidx = 0) {
    ll ret = 0;
    printde(nodes[nidx].ch, nodes[nidx].leaf, nodes[nidx].dests);
    if (nodes[nidx].leaf) {
      ret = nodes[nodes[nidx].parentIdx].nums[nodes[nidx].ch - 'a'] - 1;
      // printde(nodes[nidx].ch, ret, nodes[nodes[nidx].parentIdx].ch,
      // nodes[nodes[nidx].parentIdx].nums[nodes[nidx].ch - 'a']);
    }
    // for(auto& dest : nodes[nidx].dests){
    //     ret += calc(dest.second);
    // }
    for (int i = 0; i < 27; i++) {
      if (nodes[nidx].dests[i]) {
        ret += calc(nodes[nidx].dests[i]);
      }
    }
    return ret;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  // Node root;
  Trie root;
  vector<int> azs(27);
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    s += 'a' + 26;
    reverse(s.begin(), s.end());
    azs.assign(27, 0);
    for (auto &c : s) {
      azs[c - 'a']++;
    }
    // root.make(s, azs);
    root.add(s, azs);
  }
  cout << root.calc() << '\\n';
}
/*
a
ba
abc
dabc
eabdc
*/