Problem p02979 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 200;
const int MM = +117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("a.in", "r", stdin);
  // freopen("a.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

int k, n;
LL dp[2][NN][NN] = {};
int mod;
LL ksm(LL a, LL b) {
  LL ret = 1;
  for (; b; b >>= 1, a = a * a % mod)
    if (b & 1)
      ret = ret * a % mod;
  return ret;
}
void upd(LL &x, LL y) { x = (x + y) % mod; }
void solve1() {
  dp[0][0][0] = 1;
  int lim = k / 2;
  for (int i = 1; i <= n; ++i) {
    for (int a = 0; a <= lim; ++a) {
      for (int b = 0; b <= lim; ++b) {
        if (i & 1) {
          upd(dp[i][a][0], dp[i - 1][a][b]);
          upd(dp[i][a][b + 1], dp[i - 1][a][b]);
        } else {
          upd(dp[i][0][b], dp[i - 1][a][b]);
          upd(dp[i][a + 1][b], dp[i - 1][a][b]);
        }
      }
    }
  }
  LL ans = 0;
  for (int a = 0; a <= lim; ++a) {
    for (int b = 0; b <= lim; ++b) {
      upd(ans, dp[n][a][b]);
    }
  }
  printf("%lld\n", ans);
}
void empty(int now) {
  for (int j = 0; j <= k + 2; ++j) {
    for (int l = 0; l <= k + 2; ++l) {
      dp[now][j][l] = 0;
    }
  }
}
void cut(int now) {
  for (int j = 0; j <= k + 2; ++j) {
    for (int l = k - j + 2; l <= k + 2; ++l) {
      dp[now][j][l] = 0;
    }
  }
}
void pushodd(int now) {
  for (int j = 0; j <= k + 1; ++j) {
    for (int l = 0; l <= k + 1; ++l) {
      upd(dp[now][j][0], dp[now ^ 1][j][l]);
      upd(dp[now][j][l + 1], dp[now ^ 1][j][l]);
    }
  }
  upd(dp[now][0][k + 1], dp[now ^ 1][0][k + 1]);
}
void pusheven(int now) {
  for (int j = 1; j <= k + 2; ++j) {
    for (int l = 0; l <= k + 2; ++l) {
      upd(dp[now][j - 1][l], dp[now ^ 1][j][l]);
    }
  }
  upd(dp[now][k + 1][0], dp[now ^ 1][k + 1][0]);
  for (int j = 0; j <= k + 1; ++j) {
    for (int l = 0; l <= k + 1; ++l) {
      upd(dp[now][j][l], dp[now ^ 1][0][l]);
    }
  }
}
void solve2() {
  int t = (k + 1) / 2;
  int now = 0;
  dp[0][0][0] = 1;
  for (int i = 1; i <= k; i += 2) { // 2 4 6 | 1 3 5
    now ^= 1;
    empty(now);
    pushodd(now);
    cut(now);
  }
  for (int i = k + 2; i <= n; i += 2) {
    now ^= 1;
    empty(now);
    pushodd(now);
    now ^= 1;
    empty(now);
    pusheven(now);
    cut(now);
  }
  int cur = (n + 1) / 2 * 2 - 1 - k;
  int cnt = (n - cur) / 2;
  LL ans = 0;
  for (int j = 0; j <= cnt; ++j) {
    for (int l = 0; l <= k + 1 - j; ++l) {
      int rem = cnt - j;
      upd(ans, dp[now][j][l] * ksm(2, rem));
    }
  }
  for (int l = 0; l <= k + 1 - cnt - 1; ++l) {
    upd(ans, dp[now][cnt + 1][l]);
  }
  /*for(int i=cur+2;i<=n;i+=2){
          now^=1;
          empty(now);
          pusheven(now);
          cut(now);
  }
  for(int i=0;i<=k+1;++i){
          upd(ans,dp[now][0][i]);
          if(i<=k)upd(ans,dp[now][1][i]);
  }*/
  printf("%lld\n", ans);
}
int main() {
  // open();
  n = read();
  k = read();
  mod = read();
  if (k % 2 == 0) {
    solve1();
  } else
    solve2();
  close();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 200;
const int MM = +117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("a.in", "r", stdin);
  // freopen("a.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

int k, n;
LL dp[NN][NN][NN] = {};
int mod;
LL ksm(LL a, LL b) {
  LL ret = 1;
  for (; b; b >>= 1, a = a * a % mod)
    if (b & 1)
      ret = ret * a % mod;
  return ret;
}
void upd(LL &x, LL y) { x = (x + y) % mod; }
void solve1() {
  dp[0][0][0] = 1;
  int lim = k / 2;
  for (int i = 1; i <= n; ++i) {
    for (int a = 0; a <= lim; ++a) {
      for (int b = 0; b <= lim; ++b) {
        if (i & 1) {
          upd(dp[i][a][0], dp[i - 1][a][b]);
          upd(dp[i][a][b + 1], dp[i - 1][a][b]);
        } else {
          upd(dp[i][0][b], dp[i - 1][a][b]);
          upd(dp[i][a + 1][b], dp[i - 1][a][b]);
        }
      }
    }
  }
  LL ans = 0;
  for (int a = 0; a <= lim; ++a) {
    for (int b = 0; b <= lim; ++b) {
      upd(ans, dp[n][a][b]);
    }
  }
  printf("%lld\n", ans);
}
void empty(int now) {
  for (int j = 0; j <= k + 2; ++j) {
    for (int l = 0; l <= k + 2; ++l) {
      dp[now][j][l] = 0;
    }
  }
}
void cut(int now) {
  for (int j = 0; j <= k + 2; ++j) {
    for (int l = k - j + 2; l <= k + 2; ++l) {
      dp[now][j][l] = 0;
    }
  }
}
void pushodd(int now) {
  for (int j = 0; j <= k + 1; ++j) {
    for (int l = 0; l <= k + 1; ++l) {
      upd(dp[now][j][0], dp[now ^ 1][j][l]);
      upd(dp[now][j][l + 1], dp[now ^ 1][j][l]);
    }
  }
  upd(dp[now][0][k + 1], dp[now ^ 1][0][k + 1]);
}
void pusheven(int now) {
  for (int j = 1; j <= k + 2; ++j) {
    for (int l = 0; l <= k + 2; ++l) {
      upd(dp[now][j - 1][l], dp[now ^ 1][j][l]);
    }
  }
  upd(dp[now][k + 1][0], dp[now ^ 1][k + 1][0]);
  for (int j = 0; j <= k + 1; ++j) {
    for (int l = 0; l <= k + 1; ++l) {
      upd(dp[now][j][l], dp[now ^ 1][0][l]);
    }
  }
}
void solve2() {
  int t = (k + 1) / 2;
  int now = 0;
  dp[0][0][0] = 1;
  for (int i = 1; i <= k; i += 2) { // 2 4 6 | 1 3 5
    now ^= 1;
    empty(now);
    pushodd(now);
    cut(now);
  }
  for (int i = k + 2; i <= n; i += 2) {
    now ^= 1;
    empty(now);
    pushodd(now);
    now ^= 1;
    empty(now);
    pusheven(now);
    cut(now);
  }
  int cur = (n + 1) / 2 * 2 - 1 - k;
  int cnt = (n - cur) / 2;
  LL ans = 0;
  for (int j = 0; j <= cnt; ++j) {
    for (int l = 0; l <= k + 1 - j; ++l) {
      int rem = cnt - j;
      upd(ans, dp[now][j][l] * ksm(2, rem));
    }
  }
  for (int l = 0; l <= k + 1 - cnt - 1; ++l) {
    upd(ans, dp[now][cnt + 1][l]);
  }
  /*for(int i=cur+2;i<=n;i+=2){
          now^=1;
          empty(now);
          pusheven(now);
          cut(now);
  }
  for(int i=0;i<=k+1;++i){
          upd(ans,dp[now][0][i]);
          if(i<=k)upd(ans,dp[now][1][i]);
  }*/
  printf("%lld\n", ans);
}
int main() {
  // open();
  n = read();
  k = read();
  mod = read();
  if (k % 2 == 0) {
    solve1();
  } else
    solve2();
  close();
  return 0;
}