Problem p02634 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

long long mod = 998244353L;

template <typename T> constexpr T modpow(T a, int n) { //(a^n)%MOD
  T ret = 1;
  while (n > 0) {
    if ((n & 1) != 0) { // n%2==1
      ret = ret * a % mod;
    }
    a = a * a % mod;
    n = n / 2;
  }
  return ret;
}

std::vector<long long> fac;
std::vector<long long> ifac;

template <typename T> T modcomb(T a, T b) {
  if (a == 0 && b == 0)
    return 1;
  if (a == b || b == 0)
    return 0;
  if (a < b || a < 0 || b < 0)
    return 0;
  long long tmp = ifac[a - b] * ifac[b] % mod;
  return tmp * fac[a] % mod;
}

void combinit(int maxn) {
  fac.resize(maxn + 1);
  ifac.resize(maxn + 1);
  fac[0] = 1;
  ifac[0] = 1;
  for (long long i = 0; i < maxn; i++) {
    fac[i + 1] = fac[i] * (i + 1) % mod;
    ifac[i + 1] = ifac[i] * modpow(i + 1, mod - 2) % mod;
  }
}

using namespace std;
using ll = long long;
ll Mod = 998244353LL;
int main() {
  combinit(5000);
  int a, b, c, d;
  cin >> a >> b >> c >> d;
  vector<vector<ll>> dp(c, vector<ll>(d, 0));
  ll t = 1;
  for (int i = a; i < c; ++i) {
    t *= b;
    t %= Mod;
    dp[i][b - 1] = t;
  }
  t = 1;
  for (int i = b; i < d; ++i) {
    t *= a;
    t %= Mod;
    dp[a - 1][i] = t;
  }
  dp[a - 1][b - 1] = 1;
  for (ll i = a; i < c; ++i) {
    for (ll j = b; j < d; ++j) {
      dp[i][j] += dp[i][j - 1] * (i + 1);
      dp[i][j] %= Mod;
      dp[i][j] += dp[i - 1][j] * (j + 1);
      dp[i][j] %= Mod;

      dp[i][j] -= dp[i - 1][j - 1] * i * j;
      dp[i][j] %= Mod;
      while (dp[i][j] < 0)
        dp[i][j] += Mod;
    }
  }
  cout << dp[c - 1][d - 1] << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

long long mod = 998244353L;

template <typename T> constexpr T modpow(T a, int n) { //(a^n)%MOD
  T ret = 1;
  while (n > 0) {
    if ((n & 1) != 0) { // n%2==1
      ret = ret * a % mod;
    }
    a = a * a % mod;
    n = n / 2;
  }
  return ret;
}

std::vector<long long> fac;
std::vector<long long> ifac;

template <typename T> T modcomb(T a, T b) {
  if (a == 0 && b == 0)
    return 1;
  if (a == b || b == 0)
    return 0;
  if (a < b || a < 0 || b < 0)
    return 0;
  long long tmp = ifac[a - b] * ifac[b] % mod;
  return tmp * fac[a] % mod;
}

void combinit(int maxn) {
  fac.resize(maxn + 1);
  ifac.resize(maxn + 1);
  fac[0] = 1;
  ifac[0] = 1;
  for (long long i = 0; i < maxn; i++) {
    fac[i + 1] = fac[i] * (i + 1) % mod;
    ifac[i + 1] = ifac[i] * modpow(i + 1, mod - 2) % mod;
  }
}

using namespace std;
using ll = long long;
ll Mod = 998244353LL;
int main() {
  combinit(5000);
  int a, b, c, d;
  cin >> a >> b >> c >> d;
  vector<vector<ll>> dp(c, vector<ll>(d, 0));
  ll t = 1;
  for (int i = a; i < c; ++i) {
    t *= b;
    t %= Mod;
    dp[i][b - 1] = t;
  }
  t = 1;
  for (int i = b; i < d; ++i) {
    t *= a;
    t %= Mod;
    dp[a - 1][i] = t;
  }
  dp[a - 1][b - 1] = 1;
  for (ll i = a; i < c; ++i) {
    for (ll j = b; j < d; ++j) {
      dp[i][j] += dp[i][j - 1] * (i + 1);
      dp[i][j] %= Mod;
      dp[i][j] += dp[i - 1][j] * (j + 1);
      dp[i][j] %= Mod;

      dp[i][j] -= dp[i - 1][j - 1] * i * j;
      while (dp[i][j] < 0)
        dp[i][j] += Mod;
      dp[i][j] %= Mod;
    }
  }
  cout << dp[c - 1][d - 1] << endl;
  return 0;
}