Problem p03066 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 998244353;
const int maxn = 3005;
ll f[maxn], inv[maxn], nf[maxn], s[maxn][maxn], dp[maxn][maxn], c[maxn],
    u[maxn * 2], v[maxn * 2];
ll ans;
ll C(ll x, ll y) { return f[x] * nf[y] % M * nf[x - y] % M; }
void add(ll &x, ll y) {
  x += y;
  if (x >= M)
    x -= M;
}
void add1(int l, int r, ll x) {
  add(u[l], x);
  add(u[r + 1], M - x);
}
void add2(int l, int r, ll x) {
  add(v[l], x);
  add(v[r + 1], M - x);
}
int n, k;

int main() {
  cin >> n >> k;
  inv[1] = 1;
  for (int i = 2; i < maxn; i++)
    inv[i] = M - (M / i) * inv[M % i] % M;
  f[0] = nf[0] = 1;
  for (int i = 1; i < maxn; i++)
    f[i] = f[i - 1] * i % M, nf[i] = nf[i - 1] * inv[i] % M;
  dp[0][0] = 1;
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= min(i * 2, k); j++)
      add(dp[i + 1][j + 1], dp[i][j]), add(dp[i + 1][j + 2], dp[i][j]);
  for (int i = 0; i <= n; i++)
    for (int j = 0; j < k; j++)
      (ans += dp[i][j] * C(n, i)) %= M;
  memset(dp, 0, sizeof(dp));
  dp[0][0] = 1;
  dp[1][1] = 1;
  for (int i = 1; i < n; i++)
    for (int j = 0; j <= min(i * 2, k); j++)
      add(dp[i + 1][j + 1], dp[i][j]), add(dp[i + 1][j + 2], dp[i][j]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= k; j++)
      s[i + 1][j + 1] = dp[i][j];
  if (k % 2 == 1) {
    for (int i = (k + 1) / 2; i <= n; i++)
      (ans += C(n, i)) %= M;
  }
  for (int i = 1 + k % 2; i < k; i += 2)
    for (int p = 1; p <= i; p++)
      if (s[p][i]) {

        int r = (k - i) / 2;
        int L = (k - i + 1) / 2, R = r * 2;
        if (L <= R) {
          add1(L + p, R + p, s[p][i] * (2 * r + p + 1) % M);
          add2(L + p, R + p, M - s[p][i]);
        }
      }
  for (int i = 1; i <= n; i++)
    add(u[i], u[i - 1]), add(v[i], v[i - 1]);
  for (int i = 0; i <= n; i++)
    c[i] = (u[i] + v[i] * i) % M;
  for (int i = 1; i <= n; i++)
    (ans += c[i] * C(n, i)) %= M;
  cout << (ans + M) % M << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 998244353;
const int maxn = 6005;
ll f[maxn], inv[maxn], nf[maxn], s[maxn][maxn], dp[maxn][maxn], c[maxn],
    u[maxn * 2], v[maxn * 2];
ll ans;
ll C(ll x, ll y) { return f[x] * nf[y] % M * nf[x - y] % M; }
void add(ll &x, ll y) {
  x += y;
  if (x >= M)
    x -= M;
}
void add1(int l, int r, ll x) {
  add(u[l], x);
  add(u[r + 1], M - x);
}
void add2(int l, int r, ll x) {
  add(v[l], x);
  add(v[r + 1], M - x);
}
int n, k;

int main() {
  cin >> n >> k;
  inv[1] = 1;
  for (int i = 2; i < maxn; i++)
    inv[i] = M - (M / i) * inv[M % i] % M;
  f[0] = nf[0] = 1;
  for (int i = 1; i < maxn; i++)
    f[i] = f[i - 1] * i % M, nf[i] = nf[i - 1] * inv[i] % M;
  dp[0][0] = 1;
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= min(i * 2, k); j++)
      add(dp[i + 1][j + 1], dp[i][j]), add(dp[i + 1][j + 2], dp[i][j]);
  for (int i = 0; i <= n; i++)
    for (int j = 0; j < k; j++)
      (ans += dp[i][j] * C(n, i)) %= M;
  memset(dp, 0, sizeof(dp));
  dp[0][0] = 1;
  dp[1][1] = 1;
  for (int i = 1; i < n; i++)
    for (int j = 0; j <= min(i * 2, k); j++)
      add(dp[i + 1][j + 1], dp[i][j]), add(dp[i + 1][j + 2], dp[i][j]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j <= k; j++)
      s[i + 1][j + 1] = dp[i][j];
  if (k % 2 == 1) {
    for (int i = (k + 1) / 2; i <= n; i++)
      (ans += C(n, i)) %= M;
  }
  for (int i = 1 + k % 2; i < k; i += 2)
    for (int p = 1; p <= i; p++)
      if (s[p][i]) {

        int r = (k - i) / 2;
        int L = (k - i + 1) / 2, R = r * 2;
        if (L <= R) {
          add1(L + p, R + p, s[p][i] * (2 * r + p + 1) % M);
          add2(L + p, R + p, M - s[p][i]);
        }
      }
  for (int i = 1; i <= n; i++)
    add(u[i], u[i - 1]), add(v[i], v[i - 1]);
  for (int i = 0; i <= n; i++)
    c[i] = (u[i] + v[i] * i) % M;
  for (int i = 1; i <= n; i++)
    (ans += c[i] * C(n, i)) %= M;
  cout << (ans + M) % M << endl;
}