Problem p02979 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
const int N = 101;
#define fr(i, a, b) for (int i = a; i <= b; ++i)
#define nfr(i, a, b) for (int i = a; i >= b; --i)

int f[2][N];
int g[2][N][N][N];
int n, K, m;

inline void add(int &x, int y) {
  x += y;
  if (x >= m)
    x -= m;
}

int main() {
  scanf("%d%d%d", &n, &K, &m);
  if (K % 2 == 0) {
    int ans = 1;
    fr(t, 0, 1) {
      int len = (n + t) / 2;
      int cur = 0;
      memset(f, 0, sizeof f);
      f[0][0] = 1;
      fr(z, 1, len) {
        cur ^= 1;
        memset(f[cur], 0, sizeof f[cur]);
        fr(j, 0, K / 2) {
          if (j < K / 2)
            add(f[cur][j + 1], f[cur ^ 1][j]);
          add(f[cur][0], f[cur ^ 1][j]);
        }
      }
      int res = 0;
      fr(z, 0, len) add(res, f[cur][z]);
      ans = 1LL * ans * res % m;
    }
    printf("%d\n", ans);
  } else {
    int cur = 0;
    g[0][0][0][n] = 1;

    int ans = 0;
    fr(i, 1, n) {
      cur ^= 1;
      memset(g[cur], 0, sizeof g[cur]);
      int odd = i / 2, even = (i + 1) / 2;
      fr(j, 0, even) {
        fr(k, 0, odd) {
          fr(t, i - 1, n) {
            int to = (t % 2 != i % 2) ? n : t;
            add(g[cur][0][j][to], g[cur ^ 1][j][k][t]);
            if (t != i - 1) {
              to = t;
              if (j * 2 > K)
                to = min(to, i - k * 2 + K - 1);
              add(g[cur][k + 1][j][to], g[cur ^ 1][j][k][t]);
            }
          }
        }
      }
    }

    fr(j, 0, n) {
      fr(k, 0, n) { add(ans, g[cur][j][k][n]); }
    }
    printf("%d\n", ans);
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
const int N = 155;
#define fr(i, a, b) for (int i = a; i <= b; ++i)
#define nfr(i, a, b) for (int i = a; i >= b; --i)

int f[2][N];
int g[2][N][N][N];
int n, K, m;

inline void add(int &x, int y) {
  x += y;
  if (x >= m)
    x -= m;
}

int main() {
  scanf("%d%d%d", &n, &K, &m);
  if (K % 2 == 0) {
    int ans = 1;
    fr(t, 0, 1) {
      int len = (n + t) / 2;
      int cur = 0;
      memset(f, 0, sizeof f);
      f[0][0] = 1;
      fr(z, 1, len) {
        cur ^= 1;
        memset(f[cur], 0, sizeof f[cur]);
        fr(j, 0, K / 2) {
          if (j < K / 2)
            add(f[cur][j + 1], f[cur ^ 1][j]);
          add(f[cur][0], f[cur ^ 1][j]);
        }
      }
      int res = 0;
      fr(z, 0, len) add(res, f[cur][z]);
      ans = 1LL * ans * res % m;
    }
    printf("%d\n", ans);
  } else {
    int cur = 0;
    g[0][0][0][n] = 1;

    int ans = 0;
    fr(i, 1, n) {
      cur ^= 1;
      memset(g[cur], 0, sizeof g[cur]);
      int odd = i / 2, even = (i + 1) / 2;
      fr(j, 0, even) {
        fr(k, 0, odd) {
          fr(t, i - 1, n) {
            int to = (t % 2 != i % 2) ? n : t;
            add(g[cur][0][j][to], g[cur ^ 1][j][k][t]);
            if (t != i - 1) {
              to = t;
              if (j * 2 > K)
                to = min(to, i - k * 2 + K - 1);
              add(g[cur][k + 1][j][to], g[cur ^ 1][j][k][t]);
            }
          }
        }
      }
    }

    fr(j, 0, n) {
      fr(k, 0, n) { add(ans, g[cur][j][k][n]); }
    }
    printf("%d\n", ans);
  }
  return 0;
}