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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define fi first
#define se second
typedef pair<ll, ll> P;
using VP = vector<P>;
using VVP = vector<VP>;
using VI = vector<ll>;
using VVI = vector<VI>;
using VVVI = vector<VVI>;
const int inf = 1e9 + 7;
const ll INF = 1LL << 61;
const ll mod = 998244353;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

vector<ll> inv, fact, invfact;
void Mod_build(int n = 101010) {
  fact.resize(n + 1);
  inv.resize(n + 1);
  invfact.resize(n + 1);
  fact[0] = inv[0] = invfact[0] = 1;
  inv[1] = 1;
  for (ll i = 0; i < n; i++) {
    fact[i + 1] = fact[i] * (i + 1) % mod;
    if (i > 0)
      inv[i + 1] = mod - inv[mod % (i + 1)] * (mod / (i + 1)) % mod;
    invfact[i + 1] = invfact[i] * inv[i + 1] % mod;
  }
}
ll perm(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return fact[n] * invfact[n - k] % mod;
}
ll comb(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return (fact[n] * invfact[n - k] % mod) * invfact[k] % mod;
}
ll powmod(ll n, ll k) {
  k %= mod - 1;
  if (k < 0)
    k += mod - 1;
  ll ret = 1;
  while (k) {
    if (k & 1)
      ret = ret * n % mod;
    n = n * n % mod;
    k >>= 1;
  }
  return ret;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int i, j;
  ll a, b, c, d;
  cin >> a >> b >> c >> d;
  VVI dp(3030, VI(3030, 0));
  dp[a][b] = 1;
  VI v(3030, 0);
  for (i = a; i <= c; i++) {
    for (j = b; j <= d; j++) {
      if (i == a && j == b)
        continue;
      else if (i == a)
        dp[i][j] = dp[i][j - 1] * a;
      else if (j == b)
        dp[i][j] = dp[i - 1][j] * b;
      else {
        dp[i][j] = j * dp[i - 1][j];
        dp[i][j] %= mod;
        // dp[i][j] += powmod(i - 1, j - k - 1) * dp[i][k];
        // dp[i][j] %= mod;
        v[i] = v[i] * (i - 1) + dp[i][j - 1];
        v[i] %= mod;
        dp[i][j] += v[i];
        dp[i][j] %= mod;
      }
      dp[i][j] %= mod;
    }
  }
  cout << dp[c][d] << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define fi first
#define se second
typedef pair<ll, ll> P;
using VP = vector<P>;
using VVP = vector<VP>;
using VI = vector<ll>;
using VVI = vector<VI>;
using VVVI = vector<VVI>;
const int inf = 1e9 + 7;
const ll INF = 1LL << 61;
const ll mod = 998244353;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

vector<ll> inv, fact, invfact;
void Mod_build(int n = 101010) {
  fact.resize(n + 1);
  inv.resize(n + 1);
  invfact.resize(n + 1);
  fact[0] = inv[0] = invfact[0] = 1;
  inv[1] = 1;
  for (ll i = 0; i < n; i++) {
    fact[i + 1] = fact[i] * (i + 1) % mod;
    if (i > 0)
      inv[i + 1] = mod - inv[mod % (i + 1)] * (mod / (i + 1)) % mod;
    invfact[i + 1] = invfact[i] * inv[i + 1] % mod;
  }
}
ll perm(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return fact[n] * invfact[n - k] % mod;
}
ll comb(int n, int k) {
  if (n < 0 || k < 0 || k > n)
    return 0;
  return (fact[n] * invfact[n - k] % mod) * invfact[k] % mod;
}
ll powmod(ll n, ll k) {
  k %= mod - 1;
  if (k < 0)
    k += mod - 1;
  ll ret = 1;
  while (k) {
    if (k & 1)
      ret = ret * n % mod;
    n = n * n % mod;
    k >>= 1;
  }
  return ret;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int i, j;
  ll a, b, c, d;
  cin >> a >> b >> c >> d;
  VVI dp(3030, VI(3030, 0));
  dp[a][b] = 1;
  for (i = a; i <= c; i++) {
    for (j = b; j <= d; j++) {
      if (i == a && j == b)
        continue;
      else if (i == a)
        dp[i][j] = dp[i][j - 1] * a;
      else if (j == b)
        dp[i][j] = dp[i - 1][j] * b;
      else {
        dp[i][j] = j * dp[i - 1][j];
        dp[i][j] %= mod;
        for (int k = b; k <= j - 1; k++) {
          dp[i][j] += powmod(i - 1, j - k - 1) * dp[i][k];
          dp[i][j] %= mod;
        }
      }
      dp[i][j] %= mod;
    }
  }
  cout << dp[c][d] << endl;
}