Problem p02979 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
template <class S, class T>
ostream &operator<<(ostream &o, const pair<S, T> &p) {
  return o << "(" << p.fs << "," << p.sc << ")";
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &vc) {
  o << "{";
  for (const T &v : vc)
    o << v << ",";
  o << "}";
  return o;
}
using ll = long long;
template <class T> using V = vector<T>;
template <class T> using VV = vector<vector<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }

#ifdef LOCAL
#define show(x)                                                                \
  cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif

unsigned int mod = 1;

struct ModInt {
  using uint = unsigned int;
  using ll = long long;
  using ull = unsigned long long;

  uint v;
  ModInt() : v(0) {}
  ModInt(ll _v) : v(normS(_v % mod + mod)) {}
  explicit operator bool() const { return v != 0; }
  static uint normS(const uint &x) {
    return (x < mod) ? x : x - mod;
  } // [0 , 2*mod-1] -> [0 , mod-1]
  static ModInt make(const uint &x) {
    ModInt m;
    m.v = x;
    return m;
  }
  ModInt operator+(const ModInt &b) const { return make(normS(v + b.v)); }
  ModInt operator-(const ModInt &b) const { return make(normS(v + mod - b.v)); }
  ModInt operator-() const { return make(normS(mod - v)); }
  ModInt operator*(const ModInt &b) const { return make((ull)v * b.v % mod); }
  ModInt operator/(const ModInt &b) const { return *this * b.inv(); }
  ModInt &operator+=(const ModInt &b) { return *this = *this + b; }
  ModInt &operator-=(const ModInt &b) { return *this = *this - b; }
  ModInt &operator*=(const ModInt &b) { return *this = *this * b; }
  ModInt &operator/=(const ModInt &b) { return *this = *this / b; }
  ModInt &operator++(int) { return *this = *this + 1; }
  ModInt &operator--(int) { return *this = *this - 1; }
  ll extgcd(ll a, ll b, ll &x, ll &y) const {
    ll p[] = {a, 1, 0}, q[] = {b, 0, 1};
    while (*q) {
      ll t = *p / *q;
      rep(i, 3) swap(p[i] -= t * q[i], q[i]);
    }
    if (p[0] < 0)
      rep(i, 3) p[i] = -p[i];
    x = p[1], y = p[2];
    return p[0];
  }
  ModInt inv() const {
    ll x, y;
    extgcd(v, mod, x, y);
    return make(normS(x + mod));
  }
  ModInt pow(ll p) const {
    if (p < 0)
      return inv().pow(-p);
    ModInt a = 1;
    ModInt x = *this;
    while (p) {
      if (p & 1)
        a *= x;
      x *= x;
      p >>= 1;
    }
    return a;
  }
  bool operator==(const ModInt &b) const { return v == b.v; }
  bool operator!=(const ModInt &b) const { return v != b.v; }
  friend istream &operator>>(istream &o, ModInt &x) {
    ll tmp;
    o >> tmp;
    x = ModInt(tmp);
    return o;
  }
  friend ostream &operator<<(ostream &o, const ModInt &x) { return o << x.v; }
};
using mint = ModInt;

int N, K;
mint dp[2][80][80][80][80];

int main() {
  cin >> N >> K >> mod;
  if (K % 2 == 0) {
    K = K / 2 + 1; // o*K -> no
    VV<mint> dp(N + 1, V<mint>(K));
    dp[0][0] = 1;
    rep(i, N) rep(k, K) {
      dp[i + 1][0] += dp[i][k];
      if (k + 1 != K)
        dp[i + 1][k + 1] += dp[i][k];
    }
    mint res = 1;
    for (int n : {N / 2, (N + 1) / 2}) {
      mint s = 0;
      rep(k, K) s += dp[n][k];
      res *= s;
    }
    cout << res << endl;
    return 0;
  }
  K = (K + 1) / 2;
  dp[0][0][0][0][0] = 1;
  rep(i, N) {
    int t = i & 1;
    int nt = 1 - t;
    rep(a, K + 1) rep(b, K + 1) rep(c, K + 1) {
      dp[nt][a][b][c][0] = 0;
      dp[nt][a][b][0][c] = 0;
    }
    rep(a, K + 1) rep(b, K + 1) rep(v, K + 1) rep(_, 2) {
      if (v == 0 && _ == 0)
        continue;
      int c = v, d = 0;
      if (_)
        swap(c, d);
      if (!dp[t][a][b][c][d])
        continue;
      //			printf("[%d][%d][%d][%d]\n",a,b,c,d);

      // x
      dp[nt][b][0][d][0] += dp[t][a][b][c][d];
      // o
      if (c == 1)
        continue;
      if (a == K) {
        if (b >= K)
          continue;
        int nd = c == 0 ? 0 : c - 1;
        if (b > 0) {
          if (c == 0)
            nd = K - b;
          else
            nd = min(c - 1, K - b);
        }
        dp[nt][b][K][d][nd] += dp[t][a][b][c][d];
      } else {
        dp[nt][b][a + 1][d][c == 0 ? 0 : c - 1] += dp[t][a][b][c][d];
      }
    }
  }
  mint res = 0;
  rep(a, K + 1) rep(b, K + 1) rep(c, K + 1) rep(d, K + 1) res +=
      dp[N & 1][a][b][c][d];
  cout << res << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
template <class S, class T>
ostream &operator<<(ostream &o, const pair<S, T> &p) {
  return o << "(" << p.fs << "," << p.sc << ")";
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &vc) {
  o << "{";
  for (const T &v : vc)
    o << v << ",";
  o << "}";
  return o;
}
using ll = long long;
template <class T> using V = vector<T>;
template <class T> using VV = vector<vector<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }

#ifdef LOCAL
#define show(x)                                                                \
  cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif

unsigned int mod = 1;

struct ModInt {
  using uint = unsigned int;
  using ll = long long;
  using ull = unsigned long long;

  uint v;
  ModInt() : v(0) {}
  ModInt(ll _v) : v(normS(_v % mod + mod)) {}
  explicit operator bool() const { return v != 0; }
  static uint normS(const uint &x) {
    return (x < mod) ? x : x - mod;
  } // [0 , 2*mod-1] -> [0 , mod-1]
  static ModInt make(const uint &x) {
    ModInt m;
    m.v = x;
    return m;
  }
  ModInt operator+(const ModInt &b) const { return make(normS(v + b.v)); }
  ModInt operator-(const ModInt &b) const { return make(normS(v + mod - b.v)); }
  ModInt operator-() const { return make(normS(mod - v)); }
  ModInt operator*(const ModInt &b) const { return make((ull)v * b.v % mod); }
  ModInt operator/(const ModInt &b) const { return *this * b.inv(); }
  ModInt &operator+=(const ModInt &b) { return *this = *this + b; }
  ModInt &operator-=(const ModInt &b) { return *this = *this - b; }
  ModInt &operator*=(const ModInt &b) { return *this = *this * b; }
  ModInt &operator/=(const ModInt &b) { return *this = *this / b; }
  ModInt &operator++(int) { return *this = *this + 1; }
  ModInt &operator--(int) { return *this = *this - 1; }
  ll extgcd(ll a, ll b, ll &x, ll &y) const {
    ll p[] = {a, 1, 0}, q[] = {b, 0, 1};
    while (*q) {
      ll t = *p / *q;
      rep(i, 3) swap(p[i] -= t * q[i], q[i]);
    }
    if (p[0] < 0)
      rep(i, 3) p[i] = -p[i];
    x = p[1], y = p[2];
    return p[0];
  }
  ModInt inv() const {
    ll x, y;
    extgcd(v, mod, x, y);
    return make(normS(x + mod));
  }
  ModInt pow(ll p) const {
    if (p < 0)
      return inv().pow(-p);
    ModInt a = 1;
    ModInt x = *this;
    while (p) {
      if (p & 1)
        a *= x;
      x *= x;
      p >>= 1;
    }
    return a;
  }
  bool operator==(const ModInt &b) const { return v == b.v; }
  bool operator!=(const ModInt &b) const { return v != b.v; }
  friend istream &operator>>(istream &o, ModInt &x) {
    ll tmp;
    o >> tmp;
    x = ModInt(tmp);
    return o;
  }
  friend ostream &operator<<(ostream &o, const ModInt &x) { return o << x.v; }
};
using mint = ModInt;

int N, K;
mint dp[2][80][80][80][80];

int main() {
  cin >> N >> K >> mod;
  if (K % 2 == 0) {
    K = K / 2 + 1; // o*K -> no
    VV<mint> dp(N + 1, V<mint>(K));
    dp[0][0] = 1;
    rep(i, N) rep(k, K) {
      dp[i + 1][0] += dp[i][k];
      if (k + 1 != K)
        dp[i + 1][k + 1] += dp[i][k];
    }
    mint res = 1;
    for (int n : {N / 2, (N + 1) / 2}) {
      mint s = 0;
      rep(k, K) s += dp[n][k];
      res *= s;
    }
    cout << res << endl;
    return 0;
  }
  K = (K + 1) / 2;
  dp[0][0][0][0][0] = 1;
  rep(i, N) {
    int t = i & 1;
    int nt = 1 - t;
    rep(a, K + 1) rep(b, K + 1) rep(c, K + 1) { dp[nt][a][b][c][0] = 0; }
    rep(a, K + 1) rep(b, K + 1) rep(c, K + 1) { dp[nt][a][b][0][c] = 0; }
    rep(a, K + 1) rep(b, K + 1) rep(v, K + 1) rep(_, 2) {
      if (v == 0 && _ == 0)
        continue;
      int c = v, d = 0;
      if (_)
        swap(c, d);
      if (!dp[t][a][b][c][d])
        continue;
      //			printf("[%d][%d][%d][%d]\n",a,b,c,d);

      // x
      dp[nt][b][0][d][0] += dp[t][a][b][c][d];
      // o
      if (c == 1)
        continue;
      if (a == K) {
        if (b >= K)
          continue;
        int nd = c == 0 ? 0 : c - 1;
        if (b > 0) {
          if (c == 0)
            nd = K - b;
          else
            nd = min(c - 1, K - b);
        }
        dp[nt][b][K][d][nd] += dp[t][a][b][c][d];
      } else {
        dp[nt][b][a + 1][d][c == 0 ? 0 : c - 1] += dp[t][a][b][c][d];
      }
    }
  }
  mint res = 0;
  rep(a, K + 1) rep(b, K + 1) rep(c, K + 1) rep(d, K + 1) res +=
      dp[N & 1][a][b][c][d];
  cout << res << endl;
}