Problem p03066 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define rep(i, n) for (i = 0; i < n; i++)
#define int long long
using namespace std;

int mod = 998244353;
int N, X;
int comb[3001][6001];
int f[3001][6001];
int tate[3002][6002];
int yoko[3002][6002];

int F(int a, int b) {
  if (a < 0 || b < 0)
    return 0;
  return f[a][b];
}

int Tate(int a, int b) {
  if (a < 0 || b < 0)
    return 0;
  return tate[a][b];
}

int Yoko(int a, int b) {
  if (a < 0 || b < 0)
    return 0;
  return yoko[a][b];
}

int calc(int n, int i) {
  int j;
  int res = 0;

  for (j = n - 2 * i - 1; j <= n - i - 1; j++) {
    res += F(j, X - 2 - 2 * i);
    res %= mod;
  }
  for (j = 0; j < X - 2 - 2 * i; j++) {
    res += F(n - i - 1, j);
    res %= mod;
  }

  // cout << "calc(" << n << ", " << i << ") = " << res << endl;
  return res;
}

int solve(int n) {
  int i;
  int ret = 0;

  for (i = 0; i < n; i++) { // 22…2, i個 + 1 + 何か
    ret += calc(n, i);
    ret %= mod;
  }

  // 全部2の場合は個別に計算
  if (X % 2 == 0)
    ret += (n * 2 < X);
  else
    ret++;

  ret %= mod;
  return ret;
}

signed main() {
  int i, j;

  comb[0][0] = 1;
  for (i = 1; i < 3001; i++) {
    comb[i][0] = 1;
    for (j = 1; j < 6001; j++) {
      comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
      comb[i][j] %= mod;
    }
  }

  for (i = 0; i < 3001; i++) {
    for (j = i; j <= 2 * i; j++) {
      f[i][j] = comb[i][j - i];
    }
  }

  for (j = 0; j < 6001; j++) {
    tate[0][j] = 0;
    for (i = 1; i < 3002; i++) {
      tate[i][j] = tate[i - 1][j] + f[i - 1][j];
      tate[i][j] %= mod;
    }
  }

  for (i = 0; i < 3001; i++) {
    yoko[i][0] = 0;
    for (j = 1; j < 6002; j++) {
      yoko[i][j] = yoko[i][j - 1] + f[i][j - 1];
      yoko[i][j] %= mod;
    }
  }

  cin >> N >> X;

  int ans = 0;
  for (i = 0; i <= N; i++) { // zero
    int res = comb[N][i] * solve(N - i);
    res %= mod;
    ans += res;
    ans %= mod;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define rep(i, n) for (i = 0; i < n; i++)
#define int long long
using namespace std;

int mod = 998244353;
int N, X;
int comb[3001][6001];
int f[3001][6001];
int tate[3002][6002];
int yoko[3002][6002];

int F(int a, int b) {
  if (a < 0 || b < 0)
    return 0;
  return f[a][b];
}

int Tate(int a, int b) {
  if (a < 0 || b < 0)
    return 0;
  return tate[a][b];
}

int Yoko(int a, int b) {
  if (a < 0 || b < 0)
    return 0;
  return yoko[a][b];
}

int calc(int n, int i) {
  int j;
  int res = 0;

  int a = Tate(n - i, X - 2 - 2 * i);
  int b = Tate(n - 2 * i - 1, X - 2 - 2 * i);
  int c = Yoko(n - i - 1, X - 2 - 2 * i);
  res = (a - b + mod + c) % mod;

  // cout << "calc(" << n << ", " << i << ") = " << res << endl;
  return res;
}

int solve(int n) {
  int i;
  int ret = 0;

  for (i = 0; i < n; i++) { // 22…2, i個 + 1 + 何か
    ret += calc(n, i);
    ret %= mod;
  }

  // 全部2の場合は個別に計算
  if (X % 2 == 0)
    ret += (n * 2 < X);
  else
    ret++;

  ret %= mod;
  return ret;
}

signed main() {
  int i, j;

  comb[0][0] = 1;
  for (i = 1; i < 3001; i++) {
    comb[i][0] = 1;
    for (j = 1; j < 6001; j++) {
      comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
      comb[i][j] %= mod;
    }
  }

  for (i = 0; i < 3001; i++) {
    for (j = i; j <= 2 * i; j++) {
      f[i][j] = comb[i][j - i];
    }
  }

  for (j = 0; j < 6001; j++) {
    tate[0][j] = 0;
    for (i = 1; i < 3002; i++) {
      tate[i][j] = tate[i - 1][j] + f[i - 1][j];
      tate[i][j] %= mod;
    }
  }

  for (i = 0; i < 3001; i++) {
    yoko[i][0] = 0;
    for (j = 1; j < 6002; j++) {
      yoko[i][j] = yoko[i][j - 1] + f[i][j - 1];
      yoko[i][j] %= mod;
    }
  }

  cin >> N >> X;

  int ans = 0;
  for (i = 0; i <= N; i++) { // zero
    int res = comb[N][i] * solve(N - i);
    res %= mod;
    ans += res;
    ans %= mod;
  }
  cout << ans << endl;
  return 0;
}