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

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

typedef unsigned long long Hash;
template <class T> class RollingHash {
public:
  T src;
  vector<Hash> harr, p;

  RollingHash(T src, Hash w = 8999) : src(src) {
    p.resize(src.size() + 1);
    Hash sum = 0;
    for (int i = 0; i < src.size(); i++) {
      sum = sum * w + src[i];
      harr.push_back(sum);
    }
    p[0] = 1;
    for (int i = 1; i < p.size(); i++) {
      p[i] = p[i - 1] * w;
    }
  }
  // [l,r)
  Hash sub(int l, int r) const {
    if (l >= r)
      return 0;
    return harr[r - 1] - (l ? harr[l - 1] * p[r - l] : 0);
  }
};

struct Node {
  Hash val;
  int width;
  int center;
};
bool operator<(const Node &a, const Node &b) {
  if (a.width != b.width)
    return a.width > b.width;
  return a.val < b.val;
}

string fix(string s) {
  string r = "$";
  for (auto c : s) {
    r += c;
    r += "$";
  }
  return r;
}

Node reduce(Node node, const RollingHash<string> &s_hash) {
  node.width -= 2;
  if (node.width < 0)
    return node;
  node.val = s_hash.sub(node.center - node.width, node.center + node.width + 1);
  return node;
}

int main() {
  string S, T;
  cin >> S >> T;
  S = fix(S);
  T = fix(T);
  RollingHash<string> s_hash(S, 10007);
  RollingHash<string> t_hash(T, 10007);
  // cout << S << endl;
  auto f = [](string S) {
    RollingHash<string> s_hash(S, 10007);
    reverse(S.begin(), S.end());
    RollingHash<string> sr_hash(S, 10007);
    reverse(S.begin(), S.end());
    map<Node, int> res;
    for (int i = 0; i < S.size(); i++) {
      int i2 = S.size() - i - 1;
      int l = 0;
      int r = min<int>(i, S.size() - i - 1);
      while (l != r) {
        int m = (l + r + 1) / 2;
        if (sr_hash.sub(i2 - m, i2 + m + 1) == s_hash.sub(i - m, i + m + 1)) {
          l = m;
        } else {
          r = m - 1;
        }
      }
      if (S[i - l] == '$') {
        l--;
      }
      if (l >= 0) {
        res[{s_hash.sub(i - l, i + l + 1), l, i}]++;
      }
    }
    return res;
  };
  auto sCount = f(S);
  auto tCount = f(T);
  long long ans = 0;
  for (int i = 100001; i >= 0; i--) {
    while ((*tCount.begin()).first.width > i) {
      auto nextNode = reduce(tCount.begin()->first, t_hash);
      tCount[nextNode] += (*tCount.begin()).second;
      tCount.erase((*tCount.begin()).first);
    }
    while ((*sCount.begin()).first.width > i) {
      auto nextNode = reduce(sCount.begin()->first, s_hash);
      sCount[nextNode] += (*sCount.begin()).second;
      sCount.erase((*sCount.begin()).first);
    }
    auto it = sCount.begin();
    while (it != sCount.end() && (*it).first.width == i) {
      if (tCount.count((*it).first)) {
        ans += 1ll * tCount[(*it).first] * it->second;
      }
      it++;
    }
  }
  cout << ans << endl;
}

Error: 0

Fixed submission:

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

typedef unsigned long long Hash;
template <class T> class RollingHash {
public:
  T src;
  vector<Hash> harr, p;

  vector<int> suffixArray;
  RollingHash(T src, Hash w = 8999) : src(src) {
    p.resize(src.size() + 1);
    Hash sum = 0;
    for (int i = 0; i < src.size(); i++) {
      sum = sum * w + src[i];
      harr.push_back(sum);
    }
    p[0] = 1;
    for (int i = 1; i < p.size(); i++) {
      p[i] = p[i - 1] * w;
    }
  }
  // [l,r)
  Hash sub(int l, int r) const {
    if (l >= r)
      return 0;
    return harr[r - 1] - (l ? harr[l - 1] * p[r - l] : 0);
  }
};

struct Node {
  Hash val;
  int width;
  int center;
};
bool operator<(const Node &a, const Node &b) {
  if (a.width != b.width)
    return a.width > b.width;
  return a.val < b.val;
}

string fix(string s) {
  string r = "$";
  for (auto c : s) {
    r += c;
    r += "$";
  }
  return r;
}

Node reduce(Node node, RollingHash<string> &s_hash) {
  node.width -= 2;
  if (node.width < 0)
    return node;
  node.val = s_hash.sub(node.center - node.width, node.center + node.width + 1);
  return node;
}

int main() {
  string S, T;
  cin >> S >> T;
  S = fix(S);
  T = fix(T);
  RollingHash<string> s_hash(S, 10007);
  RollingHash<string> t_hash(T, 10007);
  // cout << S << endl;
  auto f = [](string S) {
    RollingHash<string> s_hash(S, 10007);
    reverse(S.begin(), S.end());
    RollingHash<string> sr_hash(S, 10007);
    reverse(S.begin(), S.end());
    map<Node, int> res;
    for (int i = 0; i < S.size(); i++) {
      int i2 = S.size() - i - 1;
      int l = 0;
      int r = min<int>(i, S.size() - i - 1);
      while (l != r) {
        int m = (l + r + 1) / 2;
        if (sr_hash.sub(i2 - m, i2 + m + 1) == s_hash.sub(i - m, i + m + 1)) {
          l = m;
        } else {
          r = m - 1;
        }
      }
      if (S[i - l] == '$') {
        l--;
      }
      if (l >= 0) {
        res[{s_hash.sub(i - l, i + l + 1), l, i}]++;
      }
    }
    return res;
  };

  auto sCount = f(S);
  auto tCount = f(T);
  long long ans = 0;
  for (int i = 100001; i >= 0; i--) {
    while ((*tCount.begin()).first.width > i) {
      auto nextNode = reduce(tCount.begin()->first, t_hash);
      tCount[nextNode] += (*tCount.begin()).second;
      tCount.erase((*tCount.begin()).first);
    }
    while ((*sCount.begin()).first.width > i) {
      auto nextNode = reduce(sCount.begin()->first, s_hash);
      sCount[nextNode] += (*sCount.begin()).second;
      sCount.erase((*sCount.begin()).first);
    }
    auto it = sCount.begin();
    while (it != sCount.end() && (*it).first.width == i) {
      ans += 1ll * tCount[(*it).first] * it->second;
      it++;
    }
  }
  cout << ans << endl;
}