Problem p03057 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
using ll = long long;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
const ll mod = 1e9 + 7;

template <typename T> struct SegmentTree {
private:
  int n;
  T E;
  vector<T> node;
  inline void updatef(T &x, T &y) {
    x = y;
    // x += y;
    // x = max(x,y);
    // x = min(x,y);
  }
  inline T queryf(T &x, T &y) {
    // return x*y;
    return (x + y) % mod;
    // return max(x,y);
    // return min(x,y);
  }

public:
  SegmentTree(int sz, T E_) : E(E_) {
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
  }

  SegmentTree(vector<T> &A, T E_) : E(E_) {
    int sz = A.size();
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
    rep(i, sz) node[i + n - 1] = A[i];
    for (int i = n - 2; i >= 0; --i) {
      node[i] = queryf(node[2 * i + 1], node[2 * i + 2]);
    }
  }
  void update(int k, T x) {
    k += n - 1;
    updatef(node[k], x);
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = queryf(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  //[a,b)での和を返す
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return E;
    if (a <= l && r <= b)
      return node[k];
    T xl = get(a, b, 2 * k + 1, l, (l + r) / 2);
    T xr = get(a, b, 2 * k + 2, (l + r) / 2, r);
    return queryf(xl, xr);
  }
};

vector<ll> inv, fact, invfact;
void mod_build(int n = 101010) {
  fact.resize(n + 1);
  inv.resize(n + 1);
  invfact.resize(n + 1);
  fact[0] = inv[0] = invfact[0] = 1;
  inv[1] = 1;
  rep(i, n) {
    fact[i + 1] = fact[i] * (i + 1) % mod;
    if (i > 0)
      inv[i + 1] = mod - inv[mod % (i + 1)] * (mod / (i + 1)) % mod;
    invfact[i + 1] = invfact[i] * inv[i + 1] % mod;
  }
}
ll perm(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return fact[n] * invfact[n - k] % mod;
}
ll comb(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return (fact[n] * invfact[n - k] % mod) * invfact[k] % mod;
}
ll powmod(ll n, ll k) {
  k %= mod - 1;
  if (k < 0)
    k += mod - 1;
  ll ret = 1;
  while (k) {
    if (k & 1)
      ret = ret * n % mod;
    n = n * n % mod;
    k >>= 1;
  }
  return ret;
}
int main() {
  int n, m;
  cin >> n >> m;
  string s;
  cin >> s;
  int len = 0;
  while (len < m && s[len] == s[0])
    ++len;
  if (len == m) {
    vector<ll> ans(n + 5);
    ans[0] = 2, ans[1] = 1;
    rep(i, n - 1) ans[i + 2] = (ans[i + 1] + ans[i]) % mod;
    cout << ans[n] << endl;
    return 0;
  }
  if (n % 2) {
    cout << 0 << endl;
    return 0;
  }
  if (len % 2 == 0)
    ++len;
  int cnt = 0;
  rep(i, n) {
    if (s[i] != s[0]) {
      if (cnt % 2)
        len = min(len, cnt);
      cnt = 0;
    } else
      ++cnt;
  }
  n /= 2;
  len = (len + 1) / 2;
  SegmentTree<ll> sg(n + 5, 0);
  sg.update(0, 1);
  rep(i, n + 1) {
    ll ret = sg.get(max(0, i + 1 - len), i + 1);
    sg.update(i + 1, ret);
  }
  ll ans = 0;
  rep(i, min(n, len)) { ans += sg.get(max(0, n - len), n - i); }
  cout << 2 * ans % mod << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
using ll = long long;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
const ll mod = 1e9 + 7;

template <typename T> struct SegmentTree {
private:
  int n;
  T E;
  vector<T> node;
  inline void updatef(T &x, T &y) {
    x = y;
    // x += y;
    // x = max(x,y);
    // x = min(x,y);
  }
  inline T queryf(T &x, T &y) {
    // return x*y;
    return (x + y) % mod;
    // return max(x,y);
    // return min(x,y);
  }

public:
  SegmentTree(int sz, T E_) : E(E_) {
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
  }

  SegmentTree(vector<T> &A, T E_) : E(E_) {
    int sz = A.size();
    n = 1;
    while (n < sz)
      n <<= 1;
    node.resize(2 * n - 1, E);
    rep(i, sz) node[i + n - 1] = A[i];
    for (int i = n - 2; i >= 0; --i) {
      node[i] = queryf(node[2 * i + 1], node[2 * i + 2]);
    }
  }
  void update(int k, T x) {
    k += n - 1;
    updatef(node[k], x);
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = queryf(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  //[a,b)での和を返す
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (r <= a || b <= l)
      return E;
    if (a <= l && r <= b)
      return node[k];
    T xl = get(a, b, 2 * k + 1, l, (l + r) / 2);
    T xr = get(a, b, 2 * k + 2, (l + r) / 2, r);
    return queryf(xl, xr);
  }
};

vector<ll> inv, fact, invfact;
void mod_build(int n = 101010) {
  fact.resize(n + 1);
  inv.resize(n + 1);
  invfact.resize(n + 1);
  fact[0] = inv[0] = invfact[0] = 1;
  inv[1] = 1;
  rep(i, n) {
    fact[i + 1] = fact[i] * (i + 1) % mod;
    if (i > 0)
      inv[i + 1] = mod - inv[mod % (i + 1)] * (mod / (i + 1)) % mod;
    invfact[i + 1] = invfact[i] * inv[i + 1] % mod;
  }
}
ll perm(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return fact[n] * invfact[n - k] % mod;
}
ll comb(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return (fact[n] * invfact[n - k] % mod) * invfact[k] % mod;
}
ll powmod(ll n, ll k) {
  k %= mod - 1;
  if (k < 0)
    k += mod - 1;
  ll ret = 1;
  while (k) {
    if (k & 1)
      ret = ret * n % mod;
    n = n * n % mod;
    k >>= 1;
  }
  return ret;
}
int main() {
  int n, m;
  cin >> n >> m;
  string s;
  cin >> s;
  int len = 0;
  while (len < m && s[len] == s[0])
    ++len;
  if (len == m) {
    vector<ll> ans(n + 5);
    ans[0] = 2, ans[1] = 1;
    rep(i, n - 1) ans[i + 2] = (ans[i + 1] + ans[i]) % mod;
    cout << ans[n] << endl;
    return 0;
  }
  if (n % 2) {
    cout << 0 << endl;
    return 0;
  }
  if (len % 2 == 0)
    ++len;
  int cnt = 0;
  rep(i, m) {
    if (s[i] != s[0]) {
      if (cnt % 2)
        len = min(len, cnt);
      cnt = 0;
    } else
      ++cnt;
  }
  n /= 2;
  len = (len + 1) / 2;
  SegmentTree<ll> sg(n + 5, 0);
  sg.update(0, 1);
  rep(i, n + 1) {
    ll ret = sg.get(max(0, i + 1 - len), i + 1);
    sg.update(i + 1, ret);
  }
  ll ans = 0;
  rep(i, min(n, len)) { ans += sg.get(max(0, n - len), n - i); }
  cout << 2 * ans % mod << endl;

  return 0;
}