Problem p03748 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
constexpr int mod = 1000000007;
using ll = long long;

// return a^n % mod
ll mod_pow(ll a, ll n) {
  ll ret = 1;
  ll tmp = a;
  while (n > 0) {
    if (n % 2) {
      ret *= tmp;
      ret %= mod;
    }
    tmp = tmp * tmp;
    tmp %= mod;
    n /= 2;
  }
  return ret;
}

int dp[3000][3000][2];

int main() {
  int n, m;
  cin >> n >> m;
  if (n == 1) {
    assert(false);
    cout << mod_pow(2, m) << endl;
    return 0;
  }
  if (m == 1) {
    cout << 4 << endl;
    return 0;
  }
  n--;
  m--;
  for (int i = 1; i <= m; i++)
    for (int j = 0; j <= n; j++)
      for (int k = 0; k <= 1; k++) {
        if (i == 1) { // 初期条件
          if (k == 1) {
            if (j == 0)
              dp[i][j][k] += 2;
            if (j == 1)
              dp[i][j][k]++;
          } else {
            if (j != 0)
              dp[i][j][k] += 2;
            if (j != 0 && j != 1)
              dp[i][j][k]++;
            if (j != n)
              dp[i][j][k]++;
          }
        } else { // 遷移
          ll val = 0;
          if (k == 1) {
            if (j == 0)
              val += 2LL * (dp[i - 1][j][0] + dp[i - 1][j][1]);
            else
              val += 2LL * dp[i - 1][j][1];
            if (j == 1)
              val += dp[i - 1][j - 1][0] + dp[i - 1][j - 1][1];
            else if (j != 0)
              val += dp[i - 1][j - 1][1];
            if (j != n)
              val += dp[i - 1][j + 1][1];
          } else {
            if (j != 0)
              val += 2LL * dp[i - 1][j][0];
            if (j != 0 && j != 1)
              val += dp[i - 1][j - 1][0];
            if (j != n)
              val += dp[i - 1][j + 1][0];
          }
          dp[i][j][k] = val % mod;
        }
      }
  ll ans = 0;
  for (int i = 0; i <= n; i++)
    ans += dp[m][i][1];
  ans += dp[m][0][0];
  cout << (4LL * ans) % mod
       << endl; // 問題の言い換えで答えが 1/4 になっていたので
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
constexpr int mod = 1000000007;
using ll = long long;

// return a^n % mod
ll mod_pow(ll a, ll n) {
  ll ret = 1;
  ll tmp = a;
  while (n > 0) {
    if (n % 2) {
      ret *= tmp;
      ret %= mod;
    }
    tmp = tmp * tmp;
    tmp %= mod;
    n /= 2;
  }
  return ret;
}

int dp[3000][3000][2];

int main() {
  int n, m;
  cin >> n >> m;
  if (n == 1) {
    cout << mod_pow(2, m + 1) << endl;
    return 0;
  }
  if (m == 1) {
    cout << 4 << endl;
    return 0;
  }
  n--;
  m--;
  for (int i = 1; i <= m; i++)
    for (int j = 0; j <= n; j++)
      for (int k = 0; k <= 1; k++) {
        if (i == 1) { // 初期条件
          if (k == 1) {
            if (j == 0)
              dp[i][j][k] += 2;
            if (j == 1)
              dp[i][j][k]++;
          } else {
            if (j != 0)
              dp[i][j][k] += 2;
            if (j != 0 && j != 1)
              dp[i][j][k]++;
            if (j != n)
              dp[i][j][k]++;
          }
        } else { // 遷移
          ll val = 0;
          if (k == 1) {
            if (j == 0)
              val += 2LL * (dp[i - 1][j][0] + dp[i - 1][j][1]);
            else
              val += 2LL * dp[i - 1][j][1];
            if (j == 1)
              val += dp[i - 1][j - 1][0] + dp[i - 1][j - 1][1];
            else if (j != 0)
              val += dp[i - 1][j - 1][1];
            if (j != n)
              val += dp[i - 1][j + 1][1];
          } else {
            if (j != 0)
              val += 2LL * dp[i - 1][j][0];
            if (j != 0 && j != 1)
              val += dp[i - 1][j - 1][0];
            if (j != n)
              val += dp[i - 1][j + 1][0];
          }
          dp[i][j][k] = val % mod;
        }
      }
  ll ans = 0;
  for (int i = 0; i <= n; i++)
    ans += dp[m][i][1];
  ans += dp[m][0][0];
  cout << (4LL * ans) % mod
       << endl; // 問題の言い換えで答えが 1/4 になっていたので
}