Problem p03397 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
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;
}
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod = 1000000007, MAX = 3005, INF = 1 << 30;

ll rui(ll a, ll b) {
  ll ans = 1;
  while (b > 0) {
    if (b & 1)
      ans = ans * a % mod;
    a = a * a % mod;
    b /= 2;
  }
  return ans;
}

ll dp[MAX][2];

ll ans = 0;

void solve(string &S) {
  int N = si(S);
  if (S[0] == '1' || S[0] == '?') {
    if (S[N - 1] == '0' || S[N - 1] == '?') {
      dp[0][1] = 1;
      for (int i = 1; i < N - 1; i++) {
        if (i & 1) {
          if (S[i] == '1')
            dp[i][0] = dp[i - 1][0];
          if (S[i] == '0')
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
          if (S[i] == '?')
            dp[i][0] = (dp[i - 1][0] * 2 + dp[i - 1][1]) % mod;
        } else {
          if (S[i] == '1')
            dp[i][1] = dp[i - 1][0];
          if (S[i] == '0')
            dp[i][0] = dp[i - 1][0];
          if (S[i] == '?') {
            dp[i][1] = dp[i - 1][0];
            dp[i][0] = dp[i - 1][0];
          }
        }
      }
      ans += mod - dp[N - 2][0];
      if (ans >= mod)
        ans -= mod;
    }
  }
}

ll dp2[MAX][2][2];

int main() {

  std::ifstream in("text.txt");
  std::cin.rdbuf(in.rdbuf());
  cin.tie(0);
  ios::sync_with_stdio(false);

  string S;
  cin >> S;
  int N = si(S);

  if (si(S) == 1) {
    if (S == "?" || S == "1")
      cout << 1 << endl;
    else
      cout << 0 << endl;
    return 0;
  }

  int cnt = 0;

  for (int i = 0; i < N; i++) {
    if (S[i] == '?')
      cnt++;
  }

  ans = rui(2, cnt);

  solve(S);

  reverse(all(S));
  memset(dp, 0, sizeof(dp));

  solve(S);

  reverse(all(S));

  if (S[0] == '0' || S[0] == '?') {
    if (S[N - 1] == '0' || S[N - 1] == '?') {
      dp2[0][0][0] = 1;

      for (int i = 1; i < N - 1; i++) {
        if (i & 1) {
          if (S[i] == '1') {
            dp2[i][1][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][1][1] += (dp2[i - 1][0][1]);
          }
          if (S[i] == '0') {
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
          if (S[i] == '?') {
            dp2[i][1][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][1][1] += (dp2[i - 1][0][1]);
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
        } else {
          if (S[i] == '1') {
            dp2[i][1][0] += dp2[i - 1][0][0];
            dp2[i][1][1] +=
                (dp2[i - 1][1][0] + dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
          if (S[i] == '0') {
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
          if (S[i] == '?') {
            dp2[i][1][0] += dp2[i - 1][0][0];
            dp2[i][1][1] +=
                (dp2[i - 1][1][0] + dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
        }

        dp2[i][1][0] %= mod;
        dp2[i][1][1] %= mod;
        dp2[i][0][0] %= mod;
        dp2[i][0][1] %= mod;
      }

      ll sum = 0;
      for (int a = 0; a < 2; a++)
        for (int b = 0; b < 2; b++)
          sum += dp2[N - 2][a][b];
      sum %= mod;

      ans += mod - sum;
      ans %= mod;
    }
  }

  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
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;
}
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod = 1000000007, MAX = 300005, INF = 1 << 30;

ll rui(ll a, ll b) {
  ll ans = 1;
  while (b > 0) {
    if (b & 1)
      ans = ans * a % mod;
    a = a * a % mod;
    b /= 2;
  }
  return ans;
}

ll dp[MAX][2];

ll ans = 0;

void solve(string &S) {
  int N = si(S);
  if (S[0] == '1' || S[0] == '?') {
    if (S[N - 1] == '0' || S[N - 1] == '?') {
      dp[0][1] = 1;
      for (int i = 1; i < N - 1; i++) {
        if (i & 1) {
          if (S[i] == '1')
            dp[i][0] = dp[i - 1][0];
          if (S[i] == '0')
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
          if (S[i] == '?')
            dp[i][0] = (dp[i - 1][0] * 2 + dp[i - 1][1]) % mod;
        } else {
          if (S[i] == '1')
            dp[i][1] = dp[i - 1][0];
          if (S[i] == '0')
            dp[i][0] = dp[i - 1][0];
          if (S[i] == '?') {
            dp[i][1] = dp[i - 1][0];
            dp[i][0] = dp[i - 1][0];
          }
        }
      }
      ans += mod - dp[N - 2][0];
      if (ans >= mod)
        ans -= mod;
    }
  }
}

ll dp2[MAX][2][2];

int main() {

  std::ifstream in("text.txt");
  std::cin.rdbuf(in.rdbuf());
  cin.tie(0);
  ios::sync_with_stdio(false);

  string S;
  cin >> S;
  int N = si(S);

  if (si(S) == 1) {
    if (S == "?" || S == "1")
      cout << 1 << endl;
    else
      cout << 0 << endl;
    return 0;
  }

  int cnt = 0;

  for (int i = 0; i < N; i++) {
    if (S[i] == '?')
      cnt++;
  }

  ans = rui(2, cnt);

  solve(S);

  reverse(all(S));
  memset(dp, 0, sizeof(dp));

  solve(S);

  reverse(all(S));

  if (S[0] == '0' || S[0] == '?') {
    if (S[N - 1] == '0' || S[N - 1] == '?') {
      dp2[0][0][0] = 1;

      for (int i = 1; i < N - 1; i++) {
        if (i & 1) {
          if (S[i] == '1') {
            dp2[i][1][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][1][1] += (dp2[i - 1][0][1]);
          }
          if (S[i] == '0') {
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
          if (S[i] == '?') {
            dp2[i][1][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][1][1] += (dp2[i - 1][0][1]);
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
        } else {
          if (S[i] == '1') {
            dp2[i][1][0] += dp2[i - 1][0][0];
            dp2[i][1][1] +=
                (dp2[i - 1][1][0] + dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
          if (S[i] == '0') {
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
          if (S[i] == '?') {
            dp2[i][1][0] += dp2[i - 1][0][0];
            dp2[i][1][1] +=
                (dp2[i - 1][1][0] + dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
            dp2[i][0][0] += (dp2[i - 1][0][0] + dp2[i - 1][1][0]) % mod;
            dp2[i][0][1] += (dp2[i - 1][0][1] + dp2[i - 1][1][1]) % mod;
          }
        }

        dp2[i][1][0] %= mod;
        dp2[i][1][1] %= mod;
        dp2[i][0][0] %= mod;
        dp2[i][0][1] %= mod;
      }

      ll sum = 0;
      for (int a = 0; a < 2; a++)
        for (int b = 0; b < 2; b++)
          sum += dp2[N - 2][a][b];
      sum %= mod;

      ans += mod - sum;
      ans %= mod;
    }
  }

  cout << ans << endl;
}