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

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

// [a -> b-1]
#define reps(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
// [0 -> a-1]
#define rep(i, a) reps(i, 0, (a))
// [a-1 -> b]
#define rreps(i, a, b) for (int i = (int)((a)-1); i >= (int)(b); i--)
// [a-1 -> 0]
#define rrep(i, a) rreps(i, a, 0)
#define all(v) (v).begin(), (v).end()
// next_permutation(all(v))
#define PERM(v) next_permutation(all(v))
/*sort(all(v));
 * (v).erase(unique(all(v)), v.end())*/
#define UNIQUE(v)                                                              \\
  sort(all(v));                                                                \\
  (v).erase(unique(all(v)), v.end())
// b is [a, c)
#define RANGE(a, b, c) ((a) <= (b) && (b) < (c))
// c is [a, e) && d is [b, f)
#define RANGE2D(a, b, c, d, e, f) (RANGE((a), (c), (e)) && RANGE((b), (d), (f)))
#define chmin(a, b) a = min(a, (b))
#define chmax(a, b) a = max(a, (b))
#define fcout cout << fixed << setprecision(15)
#define YES(f) cout << ((f) ? YES_STR : NO_STR) << endl;

#ifdef LOCAL_DEBUG_OPTION
namespace debug_print_n {
struct DebugPrint {
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_integral<U>::value && !is_same<U, bool>::value &&
                     !is_same<U, char>::value>
  DUMP_SUB_FUNCTION(T x) {
    cerr << x;
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_same<U, bool>::value> DUMP_SUB_FUNCTION(T x) {
    if (x)
      cerr << "True";
    else
      cerr << "False";
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_same<U, char>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << '\\'' << x << '\\'';
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_same<U, string>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << '\\"' << x << '\\"';
  }
  template <class T>
  static enable_if_t<is_same<T, const char *>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << string(x);
  }
  template <class T> static enable_if_t<true> DUMP_SUB_FUNCTION(vector<T> x) {
    cerr << '{';
    for (size_t i = 0; i < x.size(); i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(x[i]);
    }
    cerr << '}';
  }
  template <class T, size_t N>
  static enable_if_t<true> DUMP_SUB_FUNCTION(array<T, N> x) {
    cerr << '{';
    for (size_t i = 0; i < x.size(); i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(x[i]);
    }
    cerr << '}';
  }
  template <class T> static enable_if_t<true> DUMP_SUB_FUNCTION(set<T> x) {
    cerr << '[';
    size_t i = 0;
    for (auto itr = x.begin(); itr != x.end(); itr++, i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(*itr);
    }
    cerr << ']';
  }
  template <class T, class U>
  static enable_if_t<true> DUMP_SUB_FUNCTION(map<T, U> x) {
    cerr << '[';
    size_t i = 0;
    for (auto itr = x.begin(); itr != x.end(); itr++, i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(itr->first);
      cerr << " : ";
      DUMP_SUB_FUNCTION(itr->second);
    }
    cerr << ']';
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_floating_point<U>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << fixed << setprecision(5) << x;
  }
  template <class T, class U>
  static enable_if_t<true> DUMP_SUB_FUNCTION(pair<T, U> p) {
    cerr << '(';
    DUMP_SUB_FUNCTION(p.first);
    cerr << ", ";
    DUMP_SUB_FUNCTION(p.second);
    cerr << ')';
  }
  template <int num = 0, class... Args>
  static enable_if_t<num == sizeof...(Args)>
  DUMP_SUB_FUNCTION(tuple<Args...> t) {
    if (num)
      cerr << ')';
  }
  template <int num = 0, class... Args>
      static enable_if_t <
      num<sizeof...(Args)> DUMP_SUB_FUNCTION(tuple<Args...> t) {
    if (num == 0)
      cerr << '(';
    DUMP_SUB_FUNCTION(get<num>(t));
    if (num + 1 < sizeof...(Args))
      cerr << ", ";
    DUMP_SUB_FUNCTION<num + 1>(t);
  }
  template <long unsigned N>
  static enable_if_t<true> DUMP_SUB_FUNCTION(bitset<N> x) {
    cerr << x;
  }
};
void dump() { cerr << endl; }
template <class Head, class... Tail> void dump(Head &&head, Tail &&...tail) {
  DebugPrint::DUMP_SUB_FUNCTION(head);
  if (sizeof...(Tail) != 0) {
    cerr << ' ';
  }
  dump(forward<Tail>(tail)...);
}
} // namespace debug_print_n
using debug_print_n::dump;
#else
template <class... Args> void dump(Args &&...args) {}
#endif

namespace bit {
using u32 = uint_fast32_t;
using u64 = unsigned long long;
template <class T> constexpr T set(T bin, u32 pos) {
  return bin | (1ull << pos);
}
template <class T> constexpr T unset(T bin, u32 pos) {
  return bin & ~(1ull << pos);
}
template <class T> constexpr T get(T bin, u32 pos) {
  return bin & (1ull << pos);
}
template <class T> constexpr bool check(T bin, u32 pos) {
  return get(bin, pos);
}
constexpr u32 popcount(u64 bin) { return __builtin_popcountll(bin); }
} // namespace bit

template <unsigned mod> struct RollingHash {
  vector<unsigned> hashed, power;

  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \\n\\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }

  RollingHash(const string &s, unsigned base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  int LCP(const RollingHash<mod> &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

using RH = RollingHash<1000000007>;

signed main() {
  map<pair<unsigned, unsigned>, map<char, ll>> m;
  int N;
  cin >> N;
  vector<string> v(N);
  rep(i, N) cin >> v[i];
  vector<int> idx(N);
  iota(all(idx), 0);
  sort(all(idx), [&v](int a, int b) { return v[a].size() < v[b].size(); });
  ll res = 0;
  for (auto id : idx) {
    const auto &s = v[id];
    RH rhs(s, 11003);
    RH rht(s, 11027);
    auto get = [&](int l, int r) -> pair<unsigned, unsigned> {
      return {rhs.get(l, r), rht.get(l, r)};
    };
    vector<int> fl(26);
    fl[s[0] - 'a']++;
    for (int i = 1; i <= (int)s.size(); i++) {
      auto h = get(i, s.size());
      if (m.count(h) == 0) {
        if (i != s.size())
          fl[s[i] - 'a']++;
        continue;
      }
      rep(j, 26) {
        if (!fl[j])
          continue;
        res += m[h][j + 'a'];
      }
      if (i != s.size())
        fl[s[i] - 'a']++;
    }
    m[get(1, s.size())][s[0]]++;
  }
  cout << res << endl;
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

// [a -> b-1]
#define reps(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
// [0 -> a-1]
#define rep(i, a) reps(i, 0, (a))
// [a-1 -> b]
#define rreps(i, a, b) for (int i = (int)((a)-1); i >= (int)(b); i--)
// [a-1 -> 0]
#define rrep(i, a) rreps(i, a, 0)
#define all(v) (v).begin(), (v).end()
// next_permutation(all(v))
#define PERM(v) next_permutation(all(v))
/*sort(all(v));
 * (v).erase(unique(all(v)), v.end())*/
#define UNIQUE(v)                                                              \\
  sort(all(v));                                                                \\
  (v).erase(unique(all(v)), v.end())
// b is [a, c)
#define RANGE(a, b, c) ((a) <= (b) && (b) < (c))
// c is [a, e) && d is [b, f)
#define RANGE2D(a, b, c, d, e, f) (RANGE((a), (c), (e)) && RANGE((b), (d), (f)))
#define chmin(a, b) a = min(a, (b))
#define chmax(a, b) a = max(a, (b))
#define fcout cout << fixed << setprecision(15)
#define YES(f) cout << ((f) ? YES_STR : NO_STR) << endl;

#ifdef LOCAL_DEBUG_OPTION
namespace debug_print_n {
struct DebugPrint {
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_integral<U>::value && !is_same<U, bool>::value &&
                     !is_same<U, char>::value>
  DUMP_SUB_FUNCTION(T x) {
    cerr << x;
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_same<U, bool>::value> DUMP_SUB_FUNCTION(T x) {
    if (x)
      cerr << "True";
    else
      cerr << "False";
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_same<U, char>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << '\\'' << x << '\\'';
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_same<U, string>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << '\\"' << x << '\\"';
  }
  template <class T>
  static enable_if_t<is_same<T, const char *>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << string(x);
  }
  template <class T> static enable_if_t<true> DUMP_SUB_FUNCTION(vector<T> x) {
    cerr << '{';
    for (size_t i = 0; i < x.size(); i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(x[i]);
    }
    cerr << '}';
  }
  template <class T, size_t N>
  static enable_if_t<true> DUMP_SUB_FUNCTION(array<T, N> x) {
    cerr << '{';
    for (size_t i = 0; i < x.size(); i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(x[i]);
    }
    cerr << '}';
  }
  template <class T> static enable_if_t<true> DUMP_SUB_FUNCTION(set<T> x) {
    cerr << '[';
    size_t i = 0;
    for (auto itr = x.begin(); itr != x.end(); itr++, i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(*itr);
    }
    cerr << ']';
  }
  template <class T, class U>
  static enable_if_t<true> DUMP_SUB_FUNCTION(map<T, U> x) {
    cerr << '[';
    size_t i = 0;
    for (auto itr = x.begin(); itr != x.end(); itr++, i++) {
      if (i)
        cerr << ", ";
      DUMP_SUB_FUNCTION(itr->first);
      cerr << " : ";
      DUMP_SUB_FUNCTION(itr->second);
    }
    cerr << ']';
  }
  template <class T, class U = remove_const_t<remove_reference_t<T>>>
  static enable_if_t<is_floating_point<U>::value> DUMP_SUB_FUNCTION(T x) {
    cerr << fixed << setprecision(5) << x;
  }
  template <class T, class U>
  static enable_if_t<true> DUMP_SUB_FUNCTION(pair<T, U> p) {
    cerr << '(';
    DUMP_SUB_FUNCTION(p.first);
    cerr << ", ";
    DUMP_SUB_FUNCTION(p.second);
    cerr << ')';
  }
  template <int num = 0, class... Args>
  static enable_if_t<num == sizeof...(Args)>
  DUMP_SUB_FUNCTION(tuple<Args...> t) {
    if (num)
      cerr << ')';
  }
  template <int num = 0, class... Args>
      static enable_if_t <
      num<sizeof...(Args)> DUMP_SUB_FUNCTION(tuple<Args...> t) {
    if (num == 0)
      cerr << '(';
    DUMP_SUB_FUNCTION(get<num>(t));
    if (num + 1 < sizeof...(Args))
      cerr << ", ";
    DUMP_SUB_FUNCTION<num + 1>(t);
  }
  template <long unsigned N>
  static enable_if_t<true> DUMP_SUB_FUNCTION(bitset<N> x) {
    cerr << x;
  }
};
void dump() { cerr << endl; }
template <class Head, class... Tail> void dump(Head &&head, Tail &&...tail) {
  DebugPrint::DUMP_SUB_FUNCTION(head);
  if (sizeof...(Tail) != 0) {
    cerr << ' ';
  }
  dump(forward<Tail>(tail)...);
}
} // namespace debug_print_n
using debug_print_n::dump;
#else
template <class... Args> void dump(Args &&...args) {}
#endif

namespace bit {
using u32 = uint_fast32_t;
using u64 = unsigned long long;
template <class T> constexpr T set(T bin, u32 pos) {
  return bin | (1ull << pos);
}
template <class T> constexpr T unset(T bin, u32 pos) {
  return bin & ~(1ull << pos);
}
template <class T> constexpr T get(T bin, u32 pos) {
  return bin & (1ull << pos);
}
template <class T> constexpr bool check(T bin, u32 pos) {
  return get(bin, pos);
}
constexpr u32 popcount(u64 bin) { return __builtin_popcountll(bin); }
} // namespace bit

template <unsigned mod> struct RollingHash {
  vector<unsigned> hashed, power;

  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \\n\\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }

  RollingHash(const string &s, unsigned base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  int LCP(const RollingHash<mod> &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

using RH = RollingHash<1000000007>;

signed main() {
  map<unsigned int, map<char, ll>> m;
  int N;
  cin >> N;
  vector<string> v(N);
  rep(i, N) cin >> v[i];
  vector<int> idx(N);
  iota(all(idx), 0);
  sort(all(idx), [&v](int a, int b) { return v[a].size() < v[b].size(); });
  ll res = 0;
  for (auto i : idx) {
    const auto &s = v[i];
    RH rhs(s);
    vector<int> fl(26);
    fl[s[0] - 'a']++;
    for (int i = 1; i <= (int)s.size(); i++) {
      unsigned int h = rhs.get(i, s.size());
      if (m.count(h) == 0) {
        fl[s[i] - 'a']++;
        continue;
      }
      rep(i, 26) {
        if (!fl[i])
          continue;
        res += m[h][i + 'a'];
      }
      fl[s[i] - 'a']++;
    }
    m[rhs.get(1, s.size())][s[0]]++;
  }
  cout << res << endl;
  return 0;
}