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

#include <bits/stdc++.h>
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;

#pragma GCC optimize("O3")
#ifdef LOCAL
#include "/Users/lbjlc/Desktop/coding/debug_utils.h"
#else
#define print(...) ;
#define printn(...) ;
#define printg(...) ;
#define fprint(...) ;
#define fprintn(...) ;
#endif

#define rep(i, a, b) for (auto i = (a); i < (b); i++)
#define rrep(i, a, b) for (auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define pb push_back
// #define mp make_pair
#define fi first
#define se second
#define maxi(x, y) x = max(x, y)
#define mini(x, y) x = min(x, y)
// long long fact(long long n) { if(!n) return 1; return n*fact(n-1); }
// #define endl '\\n'
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define solve_testcase                                                         \\
  int T;                                                                       \\
  cin >> T;                                                                    \\
  for (int t = 1; t <= T; t++) {                                               \\
    solve(t);                                                                  \\
  }

typedef unsigned long long ull;
typedef long long ll;

typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pdd> vpdd;
typedef vector<long long> vll;
#define bd(type, op, val) bind(op<type>(), std::placeholders::_1, val)

template <class T> void make_unique(T &v) {
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
}
int geti() {
  int x;
  cin >> x;
  return x;
}
long long getll() {
  long long x;
  cin >> x;
  return x;
}
double getd() {
  double x;
  cin >> x;
  return x;
}
// pair<int, int> a(geti(), geti()) does not work
// pair<int, int> a({geti(), geti()}) works, since it uses initializer.

const int MAXN = 1e6 + 500;

void solve(int tt) { cout << "Case #" << tt << ": "; }

vector<vector<bool>> dp(1 << 20, vector<bool>(26));
struct Trie {
  int nxt[MAXN][26] = {};
  short cnt[MAXN] = {};
  short cntp[MAXN] = {};
  // short cntpc[MAXN][26] = {};
  int head = 1,
      tot = 1; // head is idx of head node, tot is the last allocated node

  int &__alloc() {
    cnt[++tot] = 0;
    memset(nxt[tot], 0, sizeof(nxt[tot]));
    return tot;
  }

  void clear() {
    tot = 0;
    head = __alloc();
  }

  int insert(const string &s) {
    int n = s.size();
    dp[n] = vector<bool>(26);
    rrep(i, n - 1, -1) {
      dp[i] = dp[i + 1];
      dp[i][s[i] - 'a'] = 1;
    }

    int tmp = head;
    int res = 0;

    cntp[tmp]++;
    for (int i = 0; i < s.size(); i++) {
      rep(j, 0, 26) if (dp[i][j] && nxt[tmp][j]) res += cnt[nxt[tmp][j]];

      if (nxt[tmp][s[i] - 'a'])
        tmp = nxt[tmp][s[i] - 'a'];
      else
        tmp = nxt[tmp][s[i] - 'a'] = __alloc();
      cntp[tmp]++;
    }
    // print("visiting node ", tmp);
    cnt[tmp]++;
    return res;
  }

} trie;

int n;
string s[MAXN];

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  // solve_testcase;

  cin >> n;
  rep(i, 0, n) {
    cin >> s[i];
    reverse(all(s[i]));
  }
  sort(s, s + n, [](const string &x, const string &y) {
    if (x.size() != y.size())
      return x.size() < y.size();
    else
      return x < y;
  });

  printn(s, n);

  ll res = 0;
  rep(i, 0, n) {
    res += trie.insert(s[i]);
    print(res);
  }
  cout << res << endl;

  return 0;
}


Error: -6
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


Fixed submission:

#include <bits/stdc++.h>
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>
// using namespace __gnu_pbds;

// #pragma GCC optimize("O3")
#ifdef LOCAL
#include "/Users/lbjlc/Desktop/coding/debug_utils.h"
#else
#define print(...) ;
#define printn(...) ;
#define printg(...) ;
#define fprint(...) ;
#define fprintn(...) ;
#endif

#define rep(i, a, b) for (auto i = (a); i < (b); i++)
#define rrep(i, a, b) for (auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define pb push_back
// #define mp make_pair
#define fi first
#define se second
#define maxi(x, y) x = max(x, y)
#define mini(x, y) x = min(x, y)
// long long fact(long long n) { if(!n) return 1; return n*fact(n-1); }
// #define endl '\\n'
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define solve_testcase                                                         \\
  int T;                                                                       \\
  cin >> T;                                                                    \\
  for (int t = 1; t <= T; t++) {                                               \\
    solve(t);                                                                  \\
  }

typedef unsigned long long ull;
typedef long long ll;

typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pdd> vpdd;
typedef vector<long long> vll;
#define bd(type, op, val) bind(op<type>(), std::placeholders::_1, val)

template <class T> void make_unique(T &v) {
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
}
int geti() {
  int x;
  cin >> x;
  return x;
}
long long getll() {
  long long x;
  cin >> x;
  return x;
}
double getd() {
  double x;
  cin >> x;
  return x;
}
// pair<int, int> a(geti(), geti()) does not work
// pair<int, int> a({geti(), geti()}) works, since it uses initializer.

const int MAXN = 1e6 + 500;

void solve(int tt) { cout << "Case #" << tt << ": "; }

vector<vector<bool>> dp(1 << 20, vector<bool>(26));
struct Trie {
  unordered_map<char, int> nxt[MAXN];
  unsigned short cnt[MAXN] = {};
  unsigned short cntp[MAXN] = {};
  // unsigned short cntpc[MAXN][26] = {};
  int head = 1,
      tot = 1; // head is idx of head node, tot is the last allocated node

  int __alloc() {
    if (tot + 1 >= MAXN)
      return 0;
    cnt[++tot] = 0;
    nxt[tot].clear();
    // memset(nxt[tot], 0, sizeof(nxt[tot]));

    return tot;
  }

  void clear() {
    tot = 0;
    head = __alloc();
  }

  void insert(const string &s, int ub) {
    int n = s.size();
    dp[n] = vector<bool>(26);
    rrep(i, n - 1, -1) {
      dp[i] = dp[i + 1];
      dp[i][s[i] - 'a'] = 1;
    }
    print(s);
    // print(dp[0]);
    // print(dp[1]);
    // print(dp[2]);
    // print(dp[3]);

    int tmp = head;

    cntp[tmp]++;
    // rep(j,0,26) if(dp[0][j]) cntpc[tmp][j]++;
    // printn(cntpc[tmp],26);

    for (int i = 0; i < s.size() && i < ub; i++) {
      if (nxt[tmp].count(s[i]))
        tmp = nxt[tmp][s[i]];
      else
        tmp = nxt[tmp][s[i]] = __alloc();

      cntp[tmp]++;
      // rep(j,0,26) if(dp[i+1][j]) cntpc[tmp][j]++;
    }
    // print("visiting node ", tmp);
    cnt[tmp]++;
  }

  int count(const string &s) {
    int n = s.size();
    int res = 0;

    int tmp = head;
    // if(n==1) res+=cntpc[tmp][s.back() - 'a'];
    for (int i = 0; i < s.size(); i++) {
      if (!nxt[tmp].count(s[i]))
        break;
      tmp = nxt[tmp][s[i]];

      // if(i==n-2) res+=cntpc[tmp][s.back() - 'a'];
      // else if(i==n-1) res+=cntp[tmp];
    }
    res += cnt[tmp];
    return res;
  }
} trie;

int n;
string s[20010];

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  // solve_testcase;

  cin >> n;
  rep(i, 0, n) {
    cin >> s[i];
    reverse(all(s[i]));
  }
  sort(s, s + n, [](const string &x, const string &y) {
    if (x.size() != y.size())
      return x.size() > y.size();
    else
      return x < y;
  });

  printn(s, n);

  ll res = 0;
  rep(i, 0, n) {
    res += trie.count(s[i]);
    trie.insert(s[i], i < n - 1 ? s[i + 1].size() + 5 : 10000000);
    print(res);
  }
  cout << res << endl;

  return 0;
}