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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class RollingHash {
private:
  static const int X[], Y[], M[];
  deque<char> dq;
  long long xp[3];
  long long hash[3];

public:
  RollingHash() {
    for (int i = 0; i < 3; ++i) {
      xp[i] = 1;
      hash[i] = 0;
    }
  }
  void push_back(char c) {
    dq.push_back(c);
    for (int i = 0; i < 3; ++i) {
      hash[i] *= X[i];
      hash[i] += c;
      hash[i] %= M[i];
      xp[i] *= X[i];
      xp[i] %= M[i];
    }
  }
  void pop_back() {
    for (int i = 0; i < 3; ++i) {
      hash[i] += M[i] - dq.back();
      hash[i] *= Y[i];
      hash[i] %= M[i];
      xp[i] *= Y[i];
      xp[i] %= M[i];
    }
    dq.pop_back();
  }
  void push_front(char c) {
    dq.push_front(c);
    for (int i = 0; i < 3; ++i) {
      hash[i] += c * xp[i];
      hash[i] %= M[i];
      xp[i] *= X[i];
      xp[i] %= M[i];
    }
  }
  void pop_front() {
    for (int i = 0; i < 3; ++i) {
      xp[i] *= Y[i];
      xp[i] %= M[i];
      hash[i] -= dq.front() * xp[i];
      hash[i] %= M[i];
      if (hash[i] < 0)
        hash[i] += M[i];
    }
    dq.pop_front();
  }
  int size() { return dq.size(); }
  bool operator==(const RollingHash &rh) {
    for (int i = 0; i < 3; ++i) {
      if (hash[i] != rh.hash[i])
        return false;
    }
    return true;
  }
  bool operator!=(const RollingHash &rh) { return !(*this == rh); }
};
const int RollingHash::X[] = {1685440109, 1389328937, 1813126193}; // 素数
const int RollingHash::Y[] = {1835226359, 1406652555,
                              643336582}; // X * Y == 1 (mod M)
const int RollingHash::M[] = {2000000087, 2000000089,
                              2000000099}; // 合同式の法（素数）

string solve(const string &s) {
  int n = s.size();
  if (n < 5 || n == 6)
    return "";

  vector<int> v(6);
  v[0] = 0;
  v[2] = (n + 3) / 3;
  v[4] = v[2] * 2;
  v[1] = n - v[4];
  v[3] = v[2] + v[1];
  v[5] = n;

  vector<RollingHash> rh(5);
  for (int i = 0; i < 5; ++i) {
    for (int j = v[i]; j < v[i + 1]; ++j) {
      rh[i].push_back(s[j]);
    }
  }

  vector<int> d = {0, -2, 1, -1, 2, 0};
  for (;;) {
    bool ok = true;
    for (int i = 0; i < 3; ++i) {
      if (rh[i] != rh[i + 2])
        ok = false;
    }
    if (ok)
      return s.substr(0, v[2]);
    if (v[1] < 3)
      return "";

    for (int i = 1; i < 5; ++i) {
      if (d[i] > 0) {
        for (int j = 0; j < d[i]; ++j) {
          rh[i - 1].push_back(s[v[i]]);
          rh[i].pop_front();
          ++v[i];
        }
      } else {
        for (int j = 0; j < -d[i]; ++j) {
          rh[i - 1].pop_back();
          rh[i].push_front(s[v[i] - 1]);
          --v[i];
        }
      }
    }
  }
}

int main() {
  string s;
  cin >> s;

  string ans = solve(s);
  if (ans == "")
    cout << "mitomerarenaiWA" << endl;
  else
    cout << "Love " << ans << '!' << endl;

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

class RollingHash {
private:
  static const int X[], Y[], M[];
  deque<char> dq;
  long long xp[3];
  long long hash[3];

public:
  RollingHash() {
    for (int i = 0; i < 3; ++i) {
      xp[i] = 1;
      hash[i] = 0;
    }
  }
  void push_back(char c) {
    dq.push_back(c);
    for (int i = 0; i < 3; ++i) {
      hash[i] *= X[i];
      hash[i] += c;
      hash[i] %= M[i];
      xp[i] *= X[i];
      xp[i] %= M[i];
    }
  }
  void pop_back() {
    for (int i = 0; i < 3; ++i) {
      hash[i] += M[i] - dq.back();
      hash[i] *= Y[i];
      hash[i] %= M[i];
      xp[i] *= Y[i];
      xp[i] %= M[i];
    }
    dq.pop_back();
  }
  void push_front(char c) {
    dq.push_front(c);
    for (int i = 0; i < 3; ++i) {
      hash[i] += c * xp[i];
      hash[i] %= M[i];
      xp[i] *= X[i];
      xp[i] %= M[i];
    }
  }
  void pop_front() {
    for (int i = 0; i < 3; ++i) {
      xp[i] *= Y[i];
      xp[i] %= M[i];
      hash[i] -= dq.front() * xp[i];
      hash[i] %= M[i];
      if (hash[i] < 0)
        hash[i] += M[i];
    }
    dq.pop_front();
  }
  bool operator==(const RollingHash &rh) {
    for (int i = 0; i < 3; ++i) {
      if (hash[i] != rh.hash[i])
        return false;
    }
    return true;
  }
  bool operator!=(const RollingHash &rh) { return !(*this == rh); }
};
const int RollingHash::X[] = {2000000011, 2000000033, 2000000063}; // 素数
const int RollingHash::Y[] = {1447368484, 1178571481,
                              1277777841}; // X * Y == 1 (mod M)
const int RollingHash::M[] = {2000000087, 2000000089,
                              2000000099}; // 合同式の法（素数）

int main() {
  string s;
  cin >> s;
  int n = s.size();

  vector<int> v(6);
  v[0] = 0;
  v[2] = (n + 3) / 3;
  v[4] = v[2] * 2;
  v[1] = n - v[4];
  v[3] = v[2] + v[1];
  v[5] = n;
  vector<int> d = {0, -2, 1, -1, 2, 0};

  vector<RollingHash> rh(5);
  for (int i = 0; i < 5; ++i) {
    for (int j = v[i]; j < v[i + 1]; ++j) {
      rh[i].push_back(s[j]);
    }
  }

  while (v[4] < n) {
    bool ok = true;
    for (int i = 0; i < 3; ++i) {
      if (rh[i] != rh[i + 2])
        ok = false;
    }
    if (ok) {
      cout << "Love " << s.substr(0, v[2]) << '!' << endl;
      return 0;
    }

    for (int i = 1; i < 5; ++i) {
      if (d[i] > 0) {
        for (int j = 0; j < d[i]; ++j) {
          rh[i - 1].push_back(s[v[i]]);
          rh[i].pop_front();
          ++v[i];
        }
      } else {
        for (int j = 0; j < -d[i]; ++j) {
          rh[i - 1].pop_back();
          rh[i].push_front(s[v[i] - 1]);
          --v[i];
        }
      }
    }
  }

  cout << "mitomerarenaiWA" << endl;
  return 0;
}