Problem p03222 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define int long long int
#define MOD(x) ((x % MOD_N) + MOD_N) % MOD_N
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORE(i, a, b) for (int i = (a); i <= (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define RFORE(i, a, b) for (int i = (b); i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SZ(c) (int)((c).size())
#define EACH(i, v) for (auto i = v.begin(); i != v.end(); ++i)
#define REACH(i, v) for (auto i = v.rbegin(); i != v.rend(); ++i)
#define LB(c, x) distance((c).begin(), lower_bound(ALL(c), x))
#define UB(c, x) distance((c).begin(), upper_bound(ALL(c), x))
#define COUNT(c, x) (upper_bound(ALL(c), x) - lower_bound(ALL(c), x))
#define UNIQUE(c)                                                              \
  SORT(c);                                                                     \
  (c).erase(unique(ALL(c)), (c).end());
#define COPY(c1, c2) copy(ALL(c1), (c2).begin())
#define EXIST(s, e) (bool)((s).find(e) != (s).end())
#define PB push_back
#define MP make_pair
#define DUMP(x) cerr << #x << " = " << (x) << endl;
#define NL cerr << endl;
using namespace std;
template <typename T, typename U> using P = pair<T, U>;
template <typename T> using V = vector<T>;
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> T sum(vector<T> &v) { return accumulate(ALL(v), T()); }
template <typename T> T sum(vector<T> &v, int a, int b) {
  return accumulate(v.begin() + a, v.begin() + b, T());
}
template <typename T> T max(vector<T> &v) { return *max_element(ALL(v)); }
template <typename T> T min(vector<T> &v) { return *min_element(ALL(v)); }
template <typename T> T max_index(vector<T> &v) {
  return distance((v).begin(), max_element(ALL(v)));
}
template <typename T> T min_index(vector<T> &v) {
  return distance((v).begin(), min_element(ALL(v)));
}

struct edge {
  int to, cost;
};

template <typename T> auto &operator<<(ostream &s, const vector<T> &v) {
  s << "[";
  bool a = 1;
  for (auto e : v) {
    s << (a ? "" : " ") << e;
    a = 0;
  }
  s << "]";
  return s;
}
template <typename T, typename U>
auto &operator<<(ostream &s, const pair<T, U> &p) {
  s << "(" << p.first << "," << p.second << ")";
  return s;
}
template <typename T> auto &operator<<(ostream &s, const set<T> &st) {
  s << "{";
  bool a = 1;
  for (auto e : st) {
    s << (a ? "" : " ") << e;
    a = 0;
  }
  s << "}";
  return s;
}
template <typename T, typename U>
auto &operator<<(ostream &s, const map<T, U> &m) {
  s << "{";
  bool a = 1;
  for (auto e : m) {
    s << (a ? "" : " ") << e.first << ":" << e.second;
    a = 0;
  }
  s << "}";
  return s;
}

const int INF = 1e18;
const int MOD_N = 1e9 + 7;

int GF_MOD = MOD_N;
struct GF {
  int mod, x;
  GF() : mod(GF_MOD), x(0) {}
  GF(int a) : mod(GF_MOD) { x = ((a % mod) + mod) % mod; }
  GF &operator=(const GF &a) {
    x = a.x;
    return *this;
  }
  GF &operator=(int a) { return *this = GF(a); }
  GF operator-() const { return GF((-x + mod) % mod); }
  GF power(int n) const {
    GF tmp = x, res = 1;
    while (n > 0) {
      if ((n & 1) == 1)
        res *= tmp;
      tmp *= tmp;
      n >>= 1;
    }
    return res;
  }
  GF inverse() const { return power(mod - 2); }
  GF &operator+=(const GF &a) {
    (x += a.x) %= mod;
    return *this;
  }
  GF &operator-=(const GF &a) { return *this += -a; }
  GF &operator*=(const GF &a) {
    (x *= a.x) %= mod;
    return *this;
  }
  GF &operator/=(const GF &a) { return *this *= a.inverse(); }
  const GF operator+(const GF &a) const { return GF(x) += a; }
  const GF operator-(const GF &a) const { return GF(x) -= a; }
  const GF operator*(const GF &a) const { return GF(x) *= a; }
  const GF operator/(const GF &a) const { return GF(x) /= a; }
  GF &operator+=(int a) { return *this += GF(a); }
  GF &operator-=(int a) { return *this -= GF(a); }
  GF &operator*=(int a) { return *this *= GF(a); }
  GF &operator/=(int a) { return *this /= GF(a); }
  const GF operator+(int a) const { return GF(x) += a; }
  const GF operator-(int a) const { return GF(x) -= a; }
  const GF operator*(int a) const { return GF(x) *= a; }
  const GF operator/(int a) const { return GF(x) /= a; }
};
auto &operator<<(ostream &s, const GF &a) {
  s << a.x;
  return s;
}

signed main() {
  int H, W, K;
  cin >> H >> W >> K;

  V<GF> fibo(W);
  fibo[0] = 1;
  fibo[1] = 1;
  FOR(i, 2, W) { fibo[i] = fibo[i - 1] + fibo[i - 2]; }

  V<V<GF>> dp(H + 1, V<GF>(W));
  dp[0][0] = 1;
  REP(h, H) {
    REP(w, W) {
      dp[h + 1][w] += dp[h][w] * fibo[w] * fibo[W - 1 - w];
      if (w != 0)
        dp[h + 1][w - 1] += dp[h][w] * fibo[w - 1] * fibo[W - 1 - w];
      if (w != W - 1)
        dp[h + 1][w + 1] += dp[h][w] * fibo[w] * fibo[W - 2 - w];
    }
  }
  cout << dp[H][K - 1] << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define int long long int
#define MOD(x) ((x % MOD_N) + MOD_N) % MOD_N
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORE(i, a, b) for (int i = (a); i <= (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define RFORE(i, a, b) for (int i = (b); i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SZ(c) (int)((c).size())
#define EACH(i, v) for (auto i = v.begin(); i != v.end(); ++i)
#define REACH(i, v) for (auto i = v.rbegin(); i != v.rend(); ++i)
#define LB(c, x) distance((c).begin(), lower_bound(ALL(c), x))
#define UB(c, x) distance((c).begin(), upper_bound(ALL(c), x))
#define COUNT(c, x) (upper_bound(ALL(c), x) - lower_bound(ALL(c), x))
#define UNIQUE(c)                                                              \
  SORT(c);                                                                     \
  (c).erase(unique(ALL(c)), (c).end());
#define COPY(c1, c2) copy(ALL(c1), (c2).begin())
#define EXIST(s, e) (bool)((s).find(e) != (s).end())
#define PB push_back
#define MP make_pair
#define DUMP(x) cerr << #x << " = " << (x) << endl;
#define NL cerr << endl;
using namespace std;
template <typename T, typename U> using P = pair<T, U>;
template <typename T> using V = vector<T>;
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> T sum(vector<T> &v) { return accumulate(ALL(v), T()); }
template <typename T> T sum(vector<T> &v, int a, int b) {
  return accumulate(v.begin() + a, v.begin() + b, T());
}
template <typename T> T max(vector<T> &v) { return *max_element(ALL(v)); }
template <typename T> T min(vector<T> &v) { return *min_element(ALL(v)); }
template <typename T> T max_index(vector<T> &v) {
  return distance((v).begin(), max_element(ALL(v)));
}
template <typename T> T min_index(vector<T> &v) {
  return distance((v).begin(), min_element(ALL(v)));
}

struct edge {
  int to, cost;
};

template <typename T> auto &operator<<(ostream &s, const vector<T> &v) {
  s << "[";
  bool a = 1;
  for (auto e : v) {
    s << (a ? "" : " ") << e;
    a = 0;
  }
  s << "]";
  return s;
}
template <typename T, typename U>
auto &operator<<(ostream &s, const pair<T, U> &p) {
  s << "(" << p.first << "," << p.second << ")";
  return s;
}
template <typename T> auto &operator<<(ostream &s, const set<T> &st) {
  s << "{";
  bool a = 1;
  for (auto e : st) {
    s << (a ? "" : " ") << e;
    a = 0;
  }
  s << "}";
  return s;
}
template <typename T, typename U>
auto &operator<<(ostream &s, const map<T, U> &m) {
  s << "{";
  bool a = 1;
  for (auto e : m) {
    s << (a ? "" : " ") << e.first << ":" << e.second;
    a = 0;
  }
  s << "}";
  return s;
}

const int INF = 1e18;
const int MOD_N = 1e9 + 7;

int GF_MOD = MOD_N;
struct GF {
  int mod, x;
  GF() : mod(GF_MOD), x(0) {}
  GF(int a) : mod(GF_MOD) { x = ((a % mod) + mod) % mod; }
  GF &operator=(const GF &a) {
    x = a.x;
    return *this;
  }
  GF &operator=(int a) { return *this = GF(a); }
  GF operator-() const { return GF((-x + mod) % mod); }
  GF power(int n) const {
    GF tmp = x, res = 1;
    while (n > 0) {
      if ((n & 1) == 1)
        res *= tmp;
      tmp *= tmp;
      n >>= 1;
    }
    return res;
  }
  GF inverse() const { return power(mod - 2); }
  GF &operator+=(const GF &a) {
    (x += a.x) %= mod;
    return *this;
  }
  GF &operator-=(const GF &a) { return *this += -a; }
  GF &operator*=(const GF &a) {
    (x *= a.x) %= mod;
    return *this;
  }
  GF &operator/=(const GF &a) { return *this *= a.inverse(); }
  const GF operator+(const GF &a) const { return GF(x) += a; }
  const GF operator-(const GF &a) const { return GF(x) -= a; }
  const GF operator*(const GF &a) const { return GF(x) *= a; }
  const GF operator/(const GF &a) const { return GF(x) /= a; }
  GF &operator+=(int a) { return *this += GF(a); }
  GF &operator-=(int a) { return *this -= GF(a); }
  GF &operator*=(int a) { return *this *= GF(a); }
  GF &operator/=(int a) { return *this /= GF(a); }
  const GF operator+(int a) const { return GF(x) += a; }
  const GF operator-(int a) const { return GF(x) -= a; }
  const GF operator*(int a) const { return GF(x) *= a; }
  const GF operator/(int a) const { return GF(x) /= a; }
};
auto &operator<<(ostream &s, const GF &a) {
  s << a.x;
  return s;
}

signed main() {
  int H, W, K;
  cin >> H >> W >> K;

  V<GF> fibo(W);
  FOR(i, 0, W) {
    if (i == 0 || i == 1)
      fibo[i] = 1;
    else
      fibo[i] = fibo[i - 1] + fibo[i - 2];
  }

  V<V<GF>> dp(H + 1, V<GF>(W));
  dp[0][0] = 1;
  REP(h, H) {
    REP(w, W) {
      dp[h + 1][w] += dp[h][w] * fibo[w] * fibo[W - 1 - w];
      if (w != 0)
        dp[h + 1][w - 1] += dp[h][w] * fibo[w - 1] * fibo[W - 1 - w];
      if (w != W - 1)
        dp[h + 1][w + 1] += dp[h][w] * fibo[w] * fibo[W - 2 - w];
    }
  }
  cout << dp[H][K - 1] << endl;

  return 0;
}