Problem p01558 (C++)

Buggy submission (status: Runtime Error):

// @snippet<sh19910711/contest:headers.cpp>
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>

// @snippet<sh19910711/contest:solution/interface.cpp>
namespace solution {
class ISolution {
public:
  virtual void init(){};
  virtual bool input() { return false; };
  virtual void output(){};
  virtual int run() = 0;
};
} // namespace solution

// @snippet<sh19910711/contest:math/extgcd.cpp>
namespace math {
template <class T> T extgcd(T a, T b, T &x, T &y) {
  for (T u = y = 1, v = x = 0; a;) {
    T q = b / a;
    std::swap(x -= q * u, u);
    std::swap(y -= q * v, v);
    std::swap(b -= q * a, a);
  }
  return b;
}
} // namespace math

// @snippet<sh19910711/contest:math/mod_inverse.cpp>
namespace math {
template <class T> T mod_inverse(T a, T m) {
  T x, y;
  extgcd(a, m, x, y);
  x %= m;
  while (x < 0)
    x += m;
  return x;
}
} // namespace math

// @snippet<sh19910711/contest:solution/solution.cpp>
namespace solution {
using namespace std;

const int SIZE = 300011;
int n, m;
string s;
string Q[SIZE];

class IRollingHash {
public:
  long long hash;
  virtual void init(){};
  virtual void pushBack(char c){};
  virtual void popBack(){};
  virtual void pushFront(char c){};
  virtual void popFront(){};
};

template <long long B, long long MOD> class RollingHash : public IRollingHash {
public:
  typedef long long LL;
  LL bases;
  LL mod;
  LL b_inv;
  std::deque<char> Q;
  RollingHash() { init(); }
  void init() {
    hash = 0;
    bases = 1;
    b_inv = math::mod_inverse(B, MOD) % MOD;
    Q.clear();
  }
  void pushBack(char c) {
    hash = (hash * B + c) % MOD;
    bases = (bases * B) % MOD;
    Q.push_back(c);
  }
  void popBack() {
    char c = Q.back();
    hash = ((hash - c + MOD) % MOD * b_inv) % MOD;
    bases = (bases * b_inv) % MOD;
    Q.pop_back();
  }
  void pushFront(char c) {
    hash = (hash + (c * bases) % MOD) % MOD;
    bases = (bases * B) % MOD;
    Q.push_front(c);
  }
  void popFront() {
    char c = Q.front();
    hash = (hash - (bases * b_inv * c) % MOD + MOD) % MOD;
    bases = (bases * b_inv) % MOD;
    Q.pop_front();
  }
  void init(string s) {
    int n = s.size();
    for (int i = 0; i < n; ++i) {
      pushBack(s[i]);
    }
  }
};

const int SIZE1 = 984617;
const int SIZE2 = 8319959;
RollingHash<29LL, SIZE1> rh1;
RollingHash<31LL, SIZE2> rh2;

const int RHC = 1;
IRollingHash *RH[RHC] = {&rh2};

void push_front(char c) {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->pushFront(c);
  }
}

void pop_front() {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->popFront();
  }
}

void push_back(char c) {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->pushBack(c);
  }
}

void pop_back() {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->popBack();
  }
}

class Solution : public ISolution {
public:
  void init() {
    rh1.init();
    rh2.init();
  }
  bool input() {
    if (!(cin >> n >> m))
      return false;
    cin >> s;
    for (int i = 0; i < m; ++i)
      cin >> Q[i];
    return true;
  }
  bool check(const int &l, const int &r) { return l >= 0 && l <= r; }
  void solve() {
    for (int i = 0; i < n; ++i)
      s[i] = s[i] - 'a' + 1;

    set<pair<long long, long long>> S;
    string sub = s.substr(0, 1);
    push_back(s[0]);

    int l = 0, r = 0;
    for (int i = 0; i < m; ++i) {
      string &q = Q[i];
      if (q[0] == 'L') {
        if (q[1] == '+') {
          l++;
          if (check(l, r)) {
            sub = sub.substr(1);
            pop_front();
          }
        } else {
          l--;
          if (check(l, r)) {
            sub = s[l] + sub;
            push_front(s[l]);
          }
        }
      } else {
        if (q[1] == '+') {
          r++;
          if (check(l, r)) {
            sub += s[r];
            push_back(s[r]);
          }
        } else {
          r--;
          if (check(l, r)) {
            sub = sub.substr(0, sub.size() - 1);
            pop_back();
          }
        }
      }

      S.insert(make_pair(RH[0]->hash, RH[1]->hash));
    }

    cout << S.size() << endl;
  }
  int run() {
    while (init(), input()) {
      solve();
      output();
    }
    return 0;
  }
};
} // namespace solution

// @snippet<sh19910711/contest:main.cpp>

int main() { return solution::Solution().run(); }

Fixed submission:

// @snippet<sh19910711/contest:headers.cpp>
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>

// @snippet<sh19910711/contest:solution/interface.cpp>
namespace solution {
class ISolution {
public:
  virtual void init(){};
  virtual bool input() { return false; };
  virtual void output(){};
  virtual int run() = 0;
};
} // namespace solution

// @snippet<sh19910711/contest:math/extgcd.cpp>
namespace math {
template <class T> T extgcd(T a, T b, T &x, T &y) {
  for (T u = y = 1, v = x = 0; a;) {
    T q = b / a;
    std::swap(x -= q * u, u);
    std::swap(y -= q * v, v);
    std::swap(b -= q * a, a);
  }
  return b;
}
} // namespace math

// @snippet<sh19910711/contest:math/mod_inverse.cpp>
namespace math {
template <class T> T mod_inverse(T a, T m) {
  T x, y;
  extgcd(a, m, x, y);
  x %= m;
  while (x < 0)
    x += m;
  return x;
}
} // namespace math

// @snippet<sh19910711/contest:solution/solution.cpp>
namespace solution {
using namespace std;

const int SIZE = 300011;
int n, m;
string s;
string Q[SIZE];

class IRollingHash {
public:
  long long hash;
  virtual void init(){};
  virtual void pushBack(char c){};
  virtual void popBack(){};
  virtual void pushFront(char c){};
  virtual void popFront(){};
};

template <long long B, long long MOD> class RollingHash : public IRollingHash {
public:
  typedef long long LL;
  LL bases;
  LL mod;
  LL b_inv;
  std::deque<char> Q;
  RollingHash() { init(); }
  void init() {
    hash = 0;
    bases = 1;
    b_inv = math::mod_inverse(B, MOD) % MOD;
    Q.clear();
  }
  void pushBack(char c) {
    hash = (hash * B + c) % MOD;
    bases = (bases * B) % MOD;
    Q.push_back(c);
  }
  void popBack() {
    char c = Q.back();
    hash = ((hash - c + MOD) % MOD * b_inv) % MOD;
    bases = (bases * b_inv) % MOD;
    Q.pop_back();
  }
  void pushFront(char c) {
    hash = (hash + (c * bases) % MOD) % MOD;
    bases = (bases * B) % MOD;
    Q.push_front(c);
  }
  void popFront() {
    char c = Q.front();
    hash = (hash - (bases * b_inv * c) % MOD + MOD) % MOD;
    bases = (bases * b_inv) % MOD;
    Q.pop_front();
  }
  void init(string s) {
    int n = s.size();
    for (int i = 0; i < n; ++i) {
      pushBack(s[i]);
    }
  }
};

const int SIZE1 = 984617;
const int SIZE2 = 8319959;
RollingHash<29LL, SIZE1> rh1;
RollingHash<31LL, SIZE2> rh2;

const int RHC = 2;
IRollingHash *RH[RHC] = {&rh2, &rh1};

void push_front(char c) {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->pushFront(c);
  }
}

void pop_front() {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->popFront();
  }
}

void push_back(char c) {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->pushBack(c);
  }
}

void pop_back() {
  for (int i = 0; i < RHC; ++i) {
    RH[i]->popBack();
  }
}

class Solution : public ISolution {
public:
  void init() {
    rh1.init();
    rh2.init();
  }
  bool input() {
    if (!(cin >> n >> m))
      return false;
    cin >> s;
    for (int i = 0; i < m; ++i)
      cin >> Q[i];
    return true;
  }
  bool check(const int &l, const int &r) { return l >= 0 && l <= r; }
  void solve() {
    for (int i = 0; i < n; ++i)
      s[i] = s[i] - 'a' + 1;

    set<pair<long long, long long>> S;
    string sub = s.substr(0, 1);
    push_back(s[0]);

    int l = 0, r = 0;
    for (int i = 0; i < m; ++i) {
      string &q = Q[i];
      if (q[0] == 'L') {
        if (q[1] == '+') {
          l++;
          if (check(l, r)) {
            sub = sub.substr(1);
            pop_front();
          }
        } else {
          l--;
          if (check(l, r)) {
            sub = s[l] + sub;
            push_front(s[l]);
          }
        }
      } else {
        if (q[1] == '+') {
          r++;
          if (check(l, r)) {
            sub += s[r];
            push_back(s[r]);
          }
        } else {
          r--;
          if (check(l, r)) {
            sub = sub.substr(0, sub.size() - 1);
            pop_back();
          }
        }
      }

      S.insert(make_pair(RH[0]->hash, RH[1]->hash));
    }

    cout << S.size() << endl;
  }
  int run() {
    while (init(), input()) {
      solve();
      output();
    }
    return 0;
  }
};
} // namespace solution

// @snippet<sh19910711/contest:main.cpp>

int main() { return solution::Solution().run(); }