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

#include <bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(), x.end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define debug(v)                                                               \\
  cout << #v << ":";                                                           \\
  for (auto x : v) {                                                           \\
    cout << x << ' ';                                                          \\
  }                                                                            \\
  cout << endl;
// #define mod 1000000007
using ll = long long;
const int INF = 1000000000;
const ll LINF = 1001002003004005006ll;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

struct IOSetup {
  IOSetup() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(12);
  }
} iosetup;

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

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++)
    os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v)
    is >> x;
  return is;
}

// hash type
using ull = unsigned long long;
struct RollingHash {
  using ull = unsigned long long;
  using uint128 = __uint128_t;
  static const ull MOD = (1ull << 61ull) - 1;
  vector<ull> hashed, power;
  const ull base;

  static inline ull add(ull a, ull b) {
    if ((a += b) >= MOD)
      a -= MOD;
    return a;
  }
  static inline ull mul(ull a, ull b) {
    uint128 c = (uint128)a * b;
    return add(c >> 61, c & MOD);
  }
  static inline ull generate_base() {
    mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
    uniform_int_distribution<ull> rand(1, RollingHash::MOD - 1);
    return rand(mt);
  }
  RollingHash() = default;
  RollingHash(const string &s, ull base) : base(base) {
    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] = add(mul(hashed[i], base), s[i]);
    }
  }
  template <typename T> RollingHash(const vector<T> &s, ull base) : base(base) {
    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] = add(mul(hashed[i], base), s[i]);
    }
  }
  // hash[l,r)
  ull get(int l, int r) const {
    return add(hashed[r], MOD - mul(hashed[l], power[r - l]));
  }
  ull concat(ull hash1, ull hash2, int hash2len) const {
    return add(mul(hash1, power[hash2len]), hash2);
  }
  int lcp(const RollingHash &b, int l1, int r1, int l2, int r2) const {
    assert(b.base == base);
    int len = min(r1 - l1, r2 - l2);
    int lw = 0, hi = len + 1;
    while (hi - lw > 1) {
      int mid = (lw + hi) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        lw = mid;
      else
        hi = mid;
    }
    return lw;
  }
};

map<ull, ll> mp[1000010];
signed main() {
  int n;
  cin >> n;
  vector<string> ss(n);
  cin >> ss;
  sort(ALL(ss), [](string a, string b) { return a.size() < b.size(); });

  auto base = RollingHash::generate_base();

  RollingHash abc("abcdefghijklmnopqrstuvwxyz", base);

  ll res = 0;
  for (auto &s : ss) {
    RollingHash RH(s, base);
    int sz = (int)s.size();

    int mask = 0;
    rep(i, sz) {
      for (int j = 0; j < 26; j++)
        if ((mask >> j) & 1) {
          auto hs = RH.concat(abc.get(j, j + 1), RH.get(i, sz), sz - i);
          auto ite = mp[sz - i + 1].find(hs);
          if (ite != mp[sz - i + 1].end())
            res += ite->second;
        }
      mask |= (1 << (s[i] - 'a'));
    }
    for (int j = 0; j < 26; j++)
      if ((mask >> j) & 1) {
        auto ite = mp[1].find(abc.get(j, j + 1));
        if (ite != mp[1].end())
          res += ite->second;
      }
    mp[sz][RH.get(0, sz)]++;
  }
  cout << res << endl;
  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(), x.end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define debug(v)                                                               \\
  cout << #v << ":";                                                           \\
  for (auto x : v) {                                                           \\
    cout << x << ' ';                                                          \\
  }                                                                            \\
  cout << endl;
#define mod 1000000007
using ll = long long;
const int INF = 1000000000;
const ll LINF = 1001002003004005006ll;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

struct IOSetup {
  IOSetup() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(12);
  }
} iosetup;

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

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++)
    os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v)
    is >> x;
  return is;
}

template <unsigned MOD> struct RollingHash {
  // hashed: hashed[0]=0でhashed[i+1]=0~iのハッシュ値
  // hashed[k]=Σ[i=0 to k]s[i]*base^(k-i-1)
  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);
      // s[i]の値をそのまま足してるから
      // sが数字になろうがアルファベットだろうがok
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= MOD)
        hashed[i + 1] -= MOD;
    }
  }
  //[l,r)のハッシュ値の取得
  // abracadabra
  // hashed[7]           =a*base^6+b*base^5+r*base^4+...+d
  // hashed[3]           =a*base^2+b*base  +r
  // hashed[3]*base^(7-3)=a*base^6+b*base^5+r*base^4
  // 引くと[l,r)のハッシュ値が求まる
  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;
  }
  // h1,h2はハッシュ値
  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= MOD)
      ret -= MOD;
    return ret;
  }
  // l1,r1 : このハッシュの区間[l1,r1)
  // 比較したいハッシュbと，それの区間[l2,r2)
  // 返り値はLongestCommonPrefixの長さ
  // 単純な文字列の比較ならgetして比べる．O(1)とO(log)違うから
  // logは定数じゃない！(戒め)
  int LCP(int l1, int r1, const RollingHash<MOD> &b, 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);
  }
};
#define mod2 1000000033

map<unsigned, ll> mp;

signed main() {

  int n;
  cin >> n;
  vector<string> ss(n);
  rep(i, n) cin >> ss[i];

  sort(ALL(ss), [](string a, string b) { return a.size() < b.size(); });

  RollingHash<mod2> abc("abcdefghijklmnopqlstuvwxyz");

  ll res = 0;
  for (auto &s : ss) {
    int sz = (int)s.size();
    vector<bool> app(26, false);
    RollingHash<mod2> RH(s);
    rep(i, sz) {
      app[s[i] - 'a'] = true;
      rep(j, 26) if (app[j]) {
        auto hs = abc.connect(abc.get(j, j + 1), RH.get(i, sz), sz - i);
        if (mp.count(hs))
          res += mp[hs];
      }
    }
    rep(j, 26) if (app[j]) {
      auto hs = abc.get(j, j + 1);
      if (mp.count(hs))
        res += mp[hs];
    }
    mp[RH.get(0, sz)]++;
  }
  cout << res << endl;
  return 0;
}