Problem p02634 (C++)

Buggy submission (status: Runtime Error):
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define mii map<int, int>
#define mll map<ll, ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vd vector<double>
#define vll vector<ll>
#define fi first
#define se second
#define si set<int>
#define sll set<ll>
#define spii set<pii>
#define vs vector<string>
#define vpii vector<pair<int, int>>
#define vpll vector<pair<long long, long long>>
#define vvi vector<vector<int>>
#define vvpii vector<vector<pii>>
#define mp make_pair
#define vvll vector<vll>
#define vsi vector<si>
#define forn(i, n) for (int i = 0; i < (n); i++)
#define rep(i, n) for (int i = 0; i < (n); i++)
#define for1(i, n) for (int i = 1; i < (n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define MANX MAXN

const ll INFLL = 1e18;
const int MAXN = 1e3 + 10;
const ll INF = 1e9;
const ll mod1 = 998244353;
const ll mod2 = 2e9 + 11;
ll dp[MAXN][MAXN];
bool was[MAXN][MAXN];
ll mult(ll a, ll b) { return (a * b) % mod1; }
ll add(ll a, ll b) {
  a += b;
  if (a >= mod1)
    return a - mod1;
  return a;
}
ll sub(ll a, ll b) {
  a -= b;
  if (a < 0)
    return a + mod1;
  return a;
}
ll a, b, c, d;
ll solve(ll n, ll m) {
  if (n < a || m < b) {
    was[n][m] = 1;
    return dp[n][m] = 0;
  }
  if (n == a && m == b) {
    was[n][m] = 1;
    return dp[n][m] = 1;
  }
  if (was[n][m])
    return dp[n][m];
  was[n][m] = 1;
  if (n == a || b == m) {
    if (n == a)
      return dp[n][m] = mult(solve(n, m - 1), n);
    else
      return dp[n][m] = mult(solve(n - 1, m), m);
  }
  ll z = solve(n - 1, m - 1);
  ll x = solve(n - 1, m);
  ll y = solve(n, m - 1);
  ll sum = add(mult(x, m), mult(y, n));
  //  cout<<n<<" "<<m<<" "<<x<<" "<<y<<" "<<z<<'\n';
  return dp[n][m] = sub(sum, mult(z, mult(n - 1, m - 1)));
}
set<vector<string>> dd[10][10];
bool wass[10][10];
void solvee(int n, int m) {
  if (n < a || m < b)
    return;
  if (n == a && m == b)
    return;
  if (wass[n][m])
    return;
  wass[n][m] = 1;
  if (n > a) {
    solvee(n - 1, m);
    for (auto to : dd[n - 1][m]) {
      string s;
      for (int i = 0; i < m; i++)
        s += 'W';
      for (int i = 0; i < m; i++) {
        s[i] = 'B';
        to.pb(s);
        dd[n][m].insert(to);
        to.pop_back();
        s[i] = 'W';
      }
    }
  }
  if (m > b) {
    solvee(n, m - 1);
    for (auto to : dd[n][m - 1]) {
      for (int i = 0; i < n; i++)
        to[i].pb('W');
      for (int i = 0; i < n; i++) {
        to[i][m - 1] = 'B';
        dd[n][m].insert(to);
        to[i][m - 1] = 'W';
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#ifdef LOCAL
  freopen("a.in", "r", stdin);
#endif
  cin >> a >> b >> c >> d;
  cout << solve(c, d) << '\n';
  //    vector <string> aa;
  //    string s;
  //    for (int i=0;i<b;i++)
  //        s+='W';
  //    for (int i=0;i<a;i++)
  //        aa.pb(s);
  //    dd[a][b].insert(aa);
  //    for (int i=a;i<=c;i++)
  //    {
  //        for (int j=b;j<=d;j++)
  //        {
  //            solvee(i,j);
  //            int x=dd[i][j].size();
  //            int y=dd[i-1][j].size();
  //            int z=dd[i][j-1].size();
  //            int who=dd[i-1][j-1].size();
  //            if (who!=0) {
  //                if (((y * j + z * i - x))%who!=0)
  //                    cout<<"bread\n";
  //                cout << (y * j + z * i - x)/who << " " << i << " " << j<<"
  //                "<<solve(i,j)<<" "<<x<< '\n';
  //            }
  //        }
  //    }
  //    for (auto to:dd[c][d])
  //    {
  //        cout<<"New:\n";
  //        for (auto too:to)
  //            cout<<too<<'\n';
  //        cout<<'\n';
  //    }
  // n=1 ?
  // recursion - matrix exponential
  // linear algebra - just a joke
  // check ios_base, MAXN, mod1 before submit
  // if debug more than 15 minutes - write stress
  // compression
}

Fixed submission:
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define mii map<int, int>
#define mll map<ll, ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vd vector<double>
#define vll vector<ll>
#define fi first
#define se second
#define si set<int>
#define sll set<ll>
#define spii set<pii>
#define vs vector<string>
#define vpii vector<pair<int, int>>
#define vpll vector<pair<long long, long long>>
#define vvi vector<vector<int>>
#define vvpii vector<vector<pii>>
#define mp make_pair
#define vvll vector<vll>
#define vsi vector<si>
#define forn(i, n) for (int i = 0; i < (n); i++)
#define rep(i, n) for (int i = 0; i < (n); i++)
#define for1(i, n) for (int i = 1; i < (n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define MANX MAXN

const ll INFLL = 1e18;
const int MAXN = 3e3 + 10;
const ll INF = 1e9;
const ll mod1 = 998244353;
const ll mod2 = 2e9 + 11;
ll dp[MAXN][MAXN];
bool was[MAXN][MAXN];
ll mult(ll a, ll b) { return (a * b) % mod1; }
ll add(ll a, ll b) {
  a += b;
  if (a >= mod1)
    return a - mod1;
  return a;
}
ll sub(ll a, ll b) {
  a -= b;
  if (a < 0)
    return a + mod1;
  return a;
}
ll a, b, c, d;
ll solve(ll n, ll m) {
  if (n < a || m < b) {
    was[n][m] = 1;
    return dp[n][m] = 0;
  }
  if (n == a && m == b) {
    was[n][m] = 1;
    return dp[n][m] = 1;
  }
  if (was[n][m])
    return dp[n][m];
  was[n][m] = 1;
  if (n == a || b == m) {
    if (n == a)
      return dp[n][m] = mult(solve(n, m - 1), n);
    else
      return dp[n][m] = mult(solve(n - 1, m), m);
  }
  ll z = solve(n - 1, m - 1);
  ll x = solve(n - 1, m);
  ll y = solve(n, m - 1);
  ll sum = add(mult(x, m), mult(y, n));
  //  cout<<n<<" "<<m<<" "<<x<<" "<<y<<" "<<z<<'\n';
  return dp[n][m] = sub(sum, mult(z, mult(n - 1, m - 1)));
}
set<vector<string>> dd[10][10];
bool wass[10][10];
void solvee(int n, int m) {
  if (n < a || m < b)
    return;
  if (n == a && m == b)
    return;
  if (wass[n][m])
    return;
  wass[n][m] = 1;
  if (n > a) {
    solvee(n - 1, m);
    for (auto to : dd[n - 1][m]) {
      string s;
      for (int i = 0; i < m; i++)
        s += 'W';
      for (int i = 0; i < m; i++) {
        s[i] = 'B';
        to.pb(s);
        dd[n][m].insert(to);
        to.pop_back();
        s[i] = 'W';
      }
    }
  }
  if (m > b) {
    solvee(n, m - 1);
    for (auto to : dd[n][m - 1]) {
      for (int i = 0; i < n; i++)
        to[i].pb('W');
      for (int i = 0; i < n; i++) {
        to[i][m - 1] = 'B';
        dd[n][m].insert(to);
        to[i][m - 1] = 'W';
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#ifdef LOCAL
  freopen("a.in", "r", stdin);
#endif
  cin >> a >> b >> c >> d;
  cout << solve(c, d) << '\n';
  //    vector <string> aa;
  //    string s;
  //    for (int i=0;i<b;i++)
  //        s+='W';
  //    for (int i=0;i<a;i++)
  //        aa.pb(s);
  //    dd[a][b].insert(aa);
  //    for (int i=a;i<=c;i++)
  //    {
  //        for (int j=b;j<=d;j++)
  //        {
  //            solvee(i,j);
  //            int x=dd[i][j].size();
  //            int y=dd[i-1][j].size();
  //            int z=dd[i][j-1].size();
  //            int who=dd[i-1][j-1].size();
  //            if (who!=0) {
  //                if (((y * j + z * i - x))%who!=0)
  //                    cout<<"bread\n";
  //                cout << (y * j + z * i - x)/who << " " << i << " " << j<<"
  //                "<<solve(i,j)<<" "<<x<< '\n';
  //            }
  //        }
  //    }
  //    for (auto to:dd[c][d])
  //    {
  //        cout<<"New:\n";
  //        for (auto too:to)
  //            cout<<too<<'\n';
  //        cout<<'\n';
  //    }
  // n=1 ?
  // recursion - matrix exponential
  // linear algebra - just a joke
  // check ios_base, MAXN, mod1 before submit
  // if debug more than 15 minutes - write stress
  // compression
}