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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REPD(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define PB(e) push_back(e)
#define FOREACH(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define BIT(n, m) (((n) >> (m)) & 1)

typedef long long ll;

template <typename S, typename T>
ostream &operator<<(ostream &out, const pair<S, T> &p) {
  out << "(" << p.first << ", " << p.second << ")";
  return out;
}

template <typename T> ostream &operator<<(ostream &out, const vector<T> &v) {
  out << "[";
  REP(i, v.size()) {
    if (i > 0)
      out << ", ";
    out << v[i];
  }
  out << "]";
  return out;
}

class Trie {
  vector<vector<int>> trie;
  vector<int> mask;

public:
  Trie() { createNode(); }

  int getRoot() { return 0; }

  int next(int state, char c) {
    assert(state < int(trie.size()));
    int ci = c - 'a';
    // cout << "nya" << " " << state << " " << ci << endl;
    if (trie[state][ci] == 0) {
      trie[state][ci] = createNode();
      // cout << "c: " << createNode()<< endl;
      // cout << trie[state][ci] << endl;
    }
    assert(trie[state][ci] > 0);
    return trie[state][ci];
  }

  int get_mask(int state) { return mask[state]; }

  void add_mask(int state, char c) { mask[state] |= 1 << (c - 'a'); }

private:
  int createNode() {
    int node_id = trie.size();
    trie.push_back(vector<int>(26));
    mask.push_back(0);
    // cout << "create: " << node_id << endl;
    return node_id;
  }
};

int main() {
  int N;
  cin >> N;
  vector<string> vs(N);
  vector<pair<int, int>> vis(N);
  REP(i, N) {
    cin >> vs[i];
    vis[i] = make_pair(vs[i].size(), i);
  }
  sort(ALL(vis));

  ll res = 0;

  Trie trie;
  REP(_i, N) {
    vector<int> remaining_mask;
    int i = vis[_i].second;
    int mask = 0;
    // cout << vs[i] << " " << res << endl;
    reverse(ALL(vs[i]));
    // cout << vs[i] << endl;
    REP(j, vs[i].size()) {
      mask |= 1 << (vs[i][vs[i].size() - 1 - j] - 'a');
      remaining_mask.push_back(mask);
    }
    reverse(ALL(remaining_mask));

    int state = trie.getRoot();
    // cout << trie.get_mask(state) << endl;
    // cout << vs[i] << " " << res << endl;
    REP(j, vs[i].size()) {
      // cout <<j << " "<< remaining_mask[j] << " " << state << " " << res <<
      // endl;
      res += __builtin_popcount(trie.get_mask(state) & remaining_mask[j]);
      if (j + 1 == int(vs[i].size())) {
        trie.add_mask(state, vs[i][j]);
      }
      // cout << i << " " <<  res << " "<< state << endl;
      state = trie.next(state, vs[i][j]);
    }
  }
  cout << res << endl;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#define REP2(i, m, n) for (int i = (int)(m); i < (int)(n); i++)
#define REPD(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define REP(i, n) REP2(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define PB(e) push_back(e)
#define FOREACH(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define MP(a, b) make_pair(a, b)
#define BIT(n, m) (((n) >> (m)) & 1)

typedef long long ll;

template <typename S, typename T>
ostream &operator<<(ostream &out, const pair<S, T> &p) {
  out << "(" << p.first << ", " << p.second << ")";
  return out;
}

template <typename T> ostream &operator<<(ostream &out, const vector<T> &v) {
  out << "[";
  REP(i, v.size()) {
    if (i > 0)
      out << ", ";
    out << v[i];
  }
  out << "]";
  return out;
}

class Trie {
  vector<vector<int>> trie;
  vector<int> mask;

public:
  Trie() { createNode(); }

  int getRoot() { return 0; }

  int next(int state, char c) {
    assert(state < int(trie.size()));
    int ci = c - 'a';
    // cout << "nya" << " " << state << " " << ci << endl;
    if (trie[state][ci] == 0) {
      trie[state][ci] = createNode();
      // cout << "c: " << createNode()<< endl;
      // cout << trie[state][ci] << endl;
    }
    assert(trie[state][ci] > 0);
    return trie[state][ci];
  }

  int get_mask(int state) { return mask[state]; }

  int add_mask(int state, char c) { mask[state] |= 1 << (c - 'a'); }

private:
  int createNode() {
    int node_id = trie.size();
    trie.push_back(vector<int>(26));
    mask.push_back(0);
    // cout << "create: " << node_id << endl;
    return node_id;
  }
};

int main() {
  int N;
  cin >> N;
  vector<string> vs(N);
  vector<pair<int, int>> vis(N);
  REP(i, N) {
    cin >> vs[i];
    vis[i] = make_pair(vs[i].size(), i);
  }
  sort(ALL(vis));

  ll res = 0;

  Trie trie;
  REP(_i, N) {
    vector<int> remaining_mask;
    int i = vis[_i].second;
    int mask = 0;
    // cout << vs[i] << " " << res << endl;
    reverse(ALL(vs[i]));
    // cout << vs[i] << endl;
    REP(j, vs[i].size()) {
      mask |= 1 << (vs[i][j] - 'a');
      remaining_mask.push_back(mask);
    }
    reverse(ALL(remaining_mask));

    int state = trie.getRoot();
    // cout << trie.get_mask(state) << endl;
    REP(j, vs[i].size()) {
      // cout << "state: " <<state << endl;
      if (j + 1 == int(vs[i].size())) {
        // cout << "mask: " <<state << endl;
        trie.add_mask(state, vs[i][j]);
      } else {
        res += __builtin_popcount(trie.get_mask(state) & remaining_mask[j]);
      }
      // cout << i << " " <<  res << " "<< state << endl;
      state = trie.next(state, vs[i][j]);
    }
  }
  cout << res << endl;
}