Problem p03222 (C++)

Buggy submission (status: Runtime Error):
#include <cmath>
#include <iostream>
#include <vector>
// https://qiita.com/ofutonfuton/items/92b1a6f4a7775f00b6ae

using namespace std;
typedef long long ll;

const ll M = pow(10, 9) + 7;

vector<ll> fac(300001);  // n!(mod M)
vector<ll> ifac(300001); // k!^{M-2} (mod M)
// k^{M-2} == k^{-1}
// a,bの範囲的にこれだけ配列を用意していけば十分

ll mpow(ll x,
        ll n) { // x^n(mod M) ←普通にpow(x,n)では溢れてしまうため，随時mod計算
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % M;
    x = x * x % M;
    n = n >> 1;
  }
  return ans;
}

ll comb(ll a, ll b) { // aCbをmod計算
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}

ll comb2(ll a, ll b) { // aCbをmod計算
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}

long long gcd(long long a, long long b) {
  long long c;

  if (a < b) {
    a += b;
    b = a - b;
    a -= b;
  }

  while (b != 0) {
    c = a % b;
    a = b;
    b = c;
  }

  return a;
}

ll lcm(ll m, ll n) {
  // 引数に０がある場合は０を返す
  if ((0 == m) || (0 == n))
    return 0;

  return ((m / gcd(m, n)) * n); // lcm = m * n / gcd(m,n)
} // lcm

pair<ll, ll> add_bunsuu(pair<ll, ll> a, pair<ll, ll> b) {
  ll bunbo = lcm(a.second, b.second);

  cout << a.first << "/" << a.second << endl;
  cout << b.first << "/" << b.second << endl;
  cout << a.first * bunbo / a.second + b.first * bunbo / b.second << "/"
       << bunbo << endl;

  return make_pair(a.first * bunbo / a.second + b.first * bunbo / b.second,
                   bunbo);
}

ll valid_amida_pattern(ll w) {
  if (w <= 0) {
    return 1;
  }
  return valid_amida_pattern(w - 1) % 1000000007 +
         valid_amida_pattern(w - 2) % 1000000007;
}
ll int_probs[105][10];
int main() {
  ll H, W, K;
  cin >> H >> W >> K;
  /*ll** int_probs = new ll*[H + 1];
  for(ll i = 0; i < H + 1; i ++){
      int_probs[i] = new ll[W];
  }*/

  if (W == 1) {
    return 1;
  }

  for (ll i = 0; i < W; i++) {
    if (i == 0) {
      int_probs[0][i] = 1;
    } else {
      int_probs[0][i] = 0;
    }
  }

  for (ll i = 1; i < H + 1; i++) {
    for (ll n = 0; n < W; n++) {
      if (n == 0) {
        int_probs[i][n] =
            int_probs[i - 1][n] * valid_amida_pattern(W - 2) % 1000000007 +
            int_probs[i - 1][n + 1] * valid_amida_pattern(W - 3) % 1000000007;
      } else if (n == W - 1) {
        int_probs[i][n] =
            int_probs[i - 1][n] * valid_amida_pattern(W - 2) % 1000000007 +
            int_probs[i - 1][n - 1] * valid_amida_pattern(W - 3) % 1000000007;
      } else {
        int_probs[i][n] = int_probs[i - 1][n] * valid_amida_pattern(n - 1) *
                              valid_amida_pattern(W - n - 2) % 1000000007 +
                          int_probs[i - 1][n + 1] * valid_amida_pattern(n - 1) *
                              valid_amida_pattern(W - n - 3) % 1000000007 +
                          int_probs[i - 1][n - 1] * valid_amida_pattern(n - 2) *
                              valid_amida_pattern(W - n - 2) % 1000000007;
      }
      int_probs[i][n] = int_probs[i][n] % 1000000007;
    }
  }
  cout << int_probs[H][K - 1] << endl;

  return 0;
}


Fixed submission:
#include <cmath>
#include <iostream>
#include <vector>
// https://qiita.com/ofutonfuton/items/92b1a6f4a7775f00b6ae

using namespace std;
typedef long long ll;

const ll M = pow(10, 9) + 7;

vector<ll> fac(300001);  // n!(mod M)
vector<ll> ifac(300001); // k!^{M-2} (mod M)
// k^{M-2} == k^{-1}
// a,bの範囲的にこれだけ配列を用意していけば十分

ll mpow(ll x,
        ll n) { // x^n(mod M) ←普通にpow(x,n)では溢れてしまうため，随時mod計算
  ll ans = 1;
  while (n != 0) {
    if (n & 1)
      ans = ans * x % M;
    x = x * x % M;
    n = n >> 1;
  }
  return ans;
}

ll comb(ll a, ll b) { // aCbをmod計算
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}

ll comb2(ll a, ll b) { // aCbをmod計算
  if (a == 0 && b == 0)
    return 1;
  if (a < b || a < 0)
    return 0;
  ll tmp = ifac[a - b] * ifac[b] % M;
  return tmp * fac[a] % M;
}

long long gcd(long long a, long long b) {
  long long c;

  if (a < b) {
    a += b;
    b = a - b;
    a -= b;
  }

  while (b != 0) {
    c = a % b;
    a = b;
    b = c;
  }

  return a;
}

ll lcm(ll m, ll n) {
  // 引数に０がある場合は０を返す
  if ((0 == m) || (0 == n))
    return 0;

  return ((m / gcd(m, n)) * n); // lcm = m * n / gcd(m,n)
} // lcm

pair<ll, ll> add_bunsuu(pair<ll, ll> a, pair<ll, ll> b) {
  ll bunbo = lcm(a.second, b.second);

  cout << a.first << "/" << a.second << endl;
  cout << b.first << "/" << b.second << endl;
  cout << a.first * bunbo / a.second + b.first * bunbo / b.second << "/"
       << bunbo << endl;

  return make_pair(a.first * bunbo / a.second + b.first * bunbo / b.second,
                   bunbo);
}

ll valid_amida_pattern(ll w) {
  if (w <= 0) {
    return 1;
  }
  return valid_amida_pattern(w - 1) % 1000000007 +
         valid_amida_pattern(w - 2) % 1000000007;
}
ll int_probs[105][10];
int main() {
  ll H, W, K;
  cin >> H >> W >> K;
  /*ll** int_probs = new ll*[H + 1];
  for(ll i = 0; i < H + 1; i ++){
      int_probs[i] = new ll[W];
  }*/

  /*if(W == 1){
      cout<< 1 <<endl;
  }*/

  for (ll i = 0; i < W; i++) {
    if (i == 0) {
      int_probs[0][i] = 1;
    } else {
      int_probs[0][i] = 0;
    }
  }

  for (ll i = 1; i < H + 1; i++) {
    for (ll n = 0; n < W; n++) {
      if (n == 0) {
        int_probs[i][n] =
            int_probs[i - 1][n] * valid_amida_pattern(W - 2) % 1000000007 +
            int_probs[i - 1][n + 1] * valid_amida_pattern(W - 3) % 1000000007;
      } else if (n == W - 1) {
        int_probs[i][n] =
            int_probs[i - 1][n] * valid_amida_pattern(W - 2) % 1000000007 +
            int_probs[i - 1][n - 1] * valid_amida_pattern(W - 3) % 1000000007;
      } else {
        int_probs[i][n] = int_probs[i - 1][n] * valid_amida_pattern(n - 1) *
                              valid_amida_pattern(W - n - 2) % 1000000007 +
                          int_probs[i - 1][n + 1] * valid_amida_pattern(n - 1) *
                              valid_amida_pattern(W - n - 3) % 1000000007 +
                          int_probs[i - 1][n - 1] * valid_amida_pattern(n - 2) *
                              valid_amida_pattern(W - n - 2) % 1000000007;
      }
      int_probs[i][n] = int_probs[i][n] % 1000000007;
    }
  }
  cout << int_probs[H][K - 1] << endl;

  return 0;
}