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

#include <bits/stdc++.h>
using namespace std;
#define TRACE(x)
#define WATCH(x) TRACE(cout << #x " = " << x << endl)
#define PRINT(x) TRACE(printf(x))
#define WATCHR(a, b)                                                           \\
  TRACE(for (auto c = a; c != b;) cout << *(c++) << " "; cout << endl)
#define WATCHC(V)                                                              \\
  TRACE({                                                                      \\
    cout << #V " = ";                                                          \\
    WATCHR(V.begin(), V.end());                                                \\
  })
#define rep(i, a, b) for (int i = (a); (i) < (b); ++(i))
#define trav(a, x) for (auto &a : x)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) static_cast<int>(x.size())
#define mp make_pair
#define fi first
#define se second

using vi = vector<int>;
using vvi = vector<vi>;
using ll = long long;
using vll = vector<ll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

void buff() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
}

template <typename T> inline void remin(T &x, const T &y) { x = min(x, y); }
template <typename T> inline void remax(T &x, const T &y) { x = max(x, y); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  string sep;
  for (const auto &x : v)
    os << sep << x, sep = ", ";
  return os << "}";
}

template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << "{";
  string sep;
  for (const auto &x : arr)
    os << sep << x, sep = ", ";
  return os << "}";
}

template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}

constexpr int ms = 1e6 + 3;

ll powmod(ll a, ll b, ll mod) {
  a %= mod;
  assert(b >= 0);
  ll res = 1;
  for (; b; b >>= 1) {
    if (b & 1)
      res = (res * a) % mod;
    a = (a * a) % mod;
  }
  return res;
}

template <ll MOD> ll norm(ll val) {
  val %= MOD;
  if (val < 0)
    val += MOD;
  return val;
}

constexpr ll p0 = 1000'000'021;
constexpr ll p1 = 1000'000'007;
constexpr int base = 31; // should be a little bit larger than the alphabet..

long long ppow[2][ms];

// Remember to call init() function!
struct Hash {
  // check if length matters to the specific problem!

  int len = 0; // does not always matter, depends on the problem
  long long H[2] = {0LL, 0LL};
  bool operator!=(const Hash &rhs) const {
    return (H[0] != rhs.H[0] || H[1] != rhs.H[1]);
  }

  // check if len should be using in this operator.. depends on the problem
  bool operator==(const Hash &rhs) const {
    return ((H[0] == rhs.H[0] && H[1] == rhs.H[1]) && len == rhs.len);
  }

  Hash(ll h0 = 0, ll h1 = 0) {
    H[0] = norm<p0>(h0);
    H[1] = norm<p1>(h1);
  }

  inline void add_back(char c) {
    H[0] = (H[0] + (c - 'a' + 1) * ppow[0][len]) % p0;
    H[1] = (H[1] + (c - 'a' + 1) * ppow[1][len]) % p1;
    ++len;
  }

  inline void add_front(char c) {
    H[0] = (H[0] * base + (c - 'a' + 1)) % p0;
    H[1] = (H[1] * base + (c - 'a' + 1)) % p1;
    ++len;
  }

  inline void removeBack(char c) {
    // assert( len > 0);
    H[0] = norm<p0>(H[0] - (c - 'a' + 1) * ppow[0][len]);
    H[1] = norm<p1>(H[1] - (c - 'a' + 1) * ppow[1][len]);
    --len;
  }

  inline void removeFront(char c) {
    // assert(len > 0);
    H[0] = norm<p0>(H[0] - (c - 'a' + 1));
    ll invMod = powmod(ppow[0][len - 1], p0 - 2, p0);
    H[0] = (H[0] * invMod) % p0;
    H[1] = norm<p1>(H[1] - (c - 'a' + 1));
    invMod = powmod(ppow[1][len - 1], p1 - 2, p1);
    H[1] = (H[1] * invMod) % p1;
    --len;
  }

  void addString(const string &s) {
    for (const char &c : s)
      add_back(c);
  }

  ll combine() { return H[0] * H[1] + H[0]; }
};

void init() {
  ppow[0][0] = ppow[1][0] = 1;
  rep(i, 1, ms) {
    ppow[0][i] = (ppow[0][i - 1] * base) % p0;
    ppow[1][i] = (ppow[1][i - 1] * base) % p1;
  }
}

map<ll, string> f[ms];
vector<string> tudo[ms];

int main() {
  init();
  buff();
  int n;
  cin >> n;
  vi single(26, 0);
  int max_len = 0;
  rep(i, 0, n) {
    string x;
    cin >> x;
    if (sz(x) == 1)
      single[x[0] - 'a']++;
    else {
      string nd;
      auto REX = Hash();
      rep(z, 1, sz(x)) REX.add_back(x[z]);
      f[sz(x) - 1][REX.combine()] += x[0];
    }
    tudo[sz(x)].push_back(x);
    remax(max_len, sz(x));
  }
  long long res = 0;
  for (int i = max_len; i >= 2; --i) {
    // vamos lidar com strings de tamanho i...
    for (const auto &v : tudo[i]) {
      vi freq(26, 0);
      for (const auto &c : v)
        freq[c - 'a']++;
      rep(j, 0, 26) if (freq[j]) res += single[j];
      auto REX = Hash();
      int search_len = 0;
      for (int add = i - 1; add > 1; --add) {
        REX.add_front(v[add]);
        freq[v[add] - 'a']--;
        search_len++;
        for (const auto &c : f[search_len][REX.combine()]) {
          if (freq[c - 'a']) {
            res++;
          }
        }
      }
    }
  }
  cout << res << '\\n';
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define TRACE(x)
#define WATCH(x) TRACE(cout << #x " = " << x << endl)
#define PRINT(x) TRACE(printf(x))
#define WATCHR(a, b)                                                           \\
  TRACE(for (auto c = a; c != b;) cout << *(c++) << " "; cout << endl)
#define WATCHC(V)                                                              \\
  TRACE({                                                                      \\
    cout << #V " = ";                                                          \\
    WATCHR(V.begin(), V.end());                                                \\
  })
#define rep(i, a, b) for (int i = (a); (i) < (b); ++(i))
#define trav(a, x) for (auto &a : x)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) static_cast<int>(x.size())
#define mp make_pair
#define fi first
#define se second

using vi = vector<int>;
using vvi = vector<vi>;
using ll = long long;
using vll = vector<ll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

void buff() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
}

constexpr ll MOD = 1e9 + 7;

inline ll pow_mod(ll a, ll b, ll mod = MOD) {
  ll res = 1;
  a %= mod;
  assert(b >= 0);
  for (; b; b >>= 1) {
    if (b & 1)
      res = (res * a) % mod;
    a = (a * a) % mod;
  }
  return res;
}

template <typename T> inline void remin(T &x, const T &y) { x = min(x, y); }
template <typename T> inline void remax(T &x, const T &y) { x = max(x, y); }

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  string sep;
  for (const auto &x : v)
    os << sep << x, sep = ", ";
  return os << "}";
}

template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << "{";
  string sep;
  for (const auto &x : arr)
    os << sep << x, sep = ", ";
  return os << "}";
}

template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}

constexpr int ms = 1e6 + 1;

map<string, string> f[ms];
vector<string> tudo[ms];

int main() {
  buff();
  int n;
  cin >> n;
  vi single(26, 0);
  int max_len = 0;
  rep(i, 0, n) {
    string x;
    cin >> x;
    if (sz(x) == 1)
      single[x[0] - 'a']++;
    else {
      string nd;
      rep(z, 1, sz(x)) nd += x[z];
      reverse(all(nd));
      f[sz(nd)][nd] += x[0];
    }
    tudo[sz(x)].push_back(x);
    remax(max_len, sz(x));
  }
  long long res = 0;
  for (int i = max_len; i >= 2; --i) {
    // vamos lidar com strings de tamanho i...
    for (const auto &v : tudo[i]) {
      vi freq(26, 0);
      for (const auto &c : v)
        freq[c - 'a']++;
      rep(j, 0, 26) if (freq[j]) res += single[j];
      string suff;
      int search_len = 0;
      for (int add = i - 1; add > 1; --add) {
        suff += v[add];
        freq[v[add] - 'a']--;
        search_len++;
        for (const auto &c : f[search_len][suff]) {
          if (freq[c - 'a']) {
            res++;
          }
        }
      }
    }
  }
  cout << res << '\\n';
  return 0;
}