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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

const ll mod = 998244353;
const double eps = 1e-8;

#ifdef DEBUG
#include "inc/debug.hpp"
#else
#define debug(...) 42
#endif

ll dp[3010][3010][3][3];
ll inv2 = 499122177;

int main() {
  ll A, B, C, D;
  cin >> A >> B >> C >> D;

  ll H = C - A + 1;
  ll W = D - B + 1;

  dp[0][0][0][0] = 1;

  for (int i = 1; i < H; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 3; ++k) {
        (dp[i][0][1][min(k + 1, 2)] += dp[i - 1][0][j][k]) %= mod;
        (dp[i][0][1][k] += (dp[i - 1][0][j][k] * (B - 1)) % mod) %= mod;
      }
    }
  }

  for (int i = 1; i < W; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 3; ++k) {
        (dp[0][i][min(j + 1, 2)][1] += dp[0][i - 1][j][k]) %= mod;
        (dp[0][i][j][1] += (dp[0][i - 1][j][k] * (A - 1)) % mod) %= mod;
      }
    }
  }

  for (int i = 1; i < H; ++i) {
    for (int j = 1; j < W; ++j) {
      for (int k = 0; k < 3; ++k) {
        for (int l = 0; l < 3; ++l) {
          // 行を増やす
          (dp[i][j][1][min(l + 1, 2)] += dp[i - 1][j][k][l]) %= mod;
          (dp[i][j][1][l] += (dp[i - 1][j][k][l] * (B + j - 1)) % mod) %= mod;

          // 列を増やす
          (dp[i][j][min(k + 1, 2)][1] += dp[i][j - 1][k][l]) %= mod;
          (dp[i][j][k][1] += (dp[i][j - 1][k][l] * (A + i - 1)) % mod) %= mod;
        }
      }
      (dp[i][j][1][1] *= inv2) %= mod;
    }
  }

  // for (int i=0; i<H; ++i) {
  //     for (int j=0; j<W; ++j) {
  //         cout << dp[i][j] << " ";
  //     }
  //     cout << endl;
  // }

  ll res = 0;
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 3; ++j) {
      (res += dp[H - 1][W - 1][i][j]) %= mod;
    }
  }
  cout << res << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

const ll mod = 998244353;
const double eps = 1e-8;

#ifdef DEBUG
#include "inc/debug.hpp"
#else
#define debug(...) 42
#endif

class mint {
public:
  ll x;
  mint(ll x = 0) : x((x % mod + mod) % mod) {}
  ll get() const { return x; }
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const { return mint(*this) += a; }
  mint operator-(const mint a) const { return mint(*this) -= a; }
  mint operator*(const mint a) const { return mint(*this) *= a; }
  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    return (t & 1) ? a * a * (*this) : a * a;
  }
  operator ll() const { return x; }
  operator string() const { return to_string(x); }
  friend istream &operator>>(istream &is, mint &a) {
    is >> a.x;
    return is;
  }

  // for prime mod
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const { return mint(*this) /= a; }
};

mint dp[3010][3010][3][3];

int main() {
  int A, B, C, D;
  cin >> A >> B >> C >> D;

  int H = C - A + 1;
  int W = D - B + 1;

  dp[0][0][0][0] = mint(1);

  for (int i = 1; i < H; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 3; ++k) {
        dp[i][0][1][min(k + 1, 2)] += dp[i - 1][0][j][k];
        dp[i][0][1][k] += dp[i - 1][0][j][k] * mint(B - 1);
      }
    }
  }

  for (int i = 1; i < W; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 3; ++k) {
        dp[0][i][min(j + 1, 2)][1] += dp[0][i - 1][j][k];
        dp[0][i][j][1] += dp[0][i - 1][j][k] * mint(A - 1);
      }
    }
  }

  for (int i = 1; i < H; ++i) {
    for (int j = 1; j < W; ++j) {
      for (int k = 0; k < 3; ++k) {
        for (int l = 0; l < 3; ++l) {
          // 行を増やす
          dp[i][j][1][min(l + 1, 2)] += dp[i - 1][j][k][l];
          dp[i][j][1][l] += dp[i - 1][j][k][l] * mint(B + j - 1);

          // 列を増やす
          dp[i][j][min(k + 1, 2)][1] += dp[i][j - 1][k][l];
          dp[i][j][k][1] += dp[i][j - 1][k][l] * mint(A + i - 1);
        }
      }
      dp[i][j][1][1] /= mint(2);
    }
  }

  // for (int i=0; i<H; ++i) {
  //     for (int j=0; j<W; ++j) {
  //         cout << dp[i][j] << " ";
  //     }
  //     cout << endl;
  // }

  mint res(0);
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 3; ++j) {
      res += dp[H - 1][W - 1][i][j];
    }
  }
  cout << res << endl;

  return 0;
}