Problem p02907 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define of(i, l, r) for (int i = l; i >= r; i--)
#define fe(i, u) for (int i = head[u]; i; i = e[i].next)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
inline void open(const char *s) {
#ifndef ONLINE_JUDGE
  char str[20];
  sprintf(str, "%s.in", s);
  freopen(str, "r", stdin);
  //	sprintf(str,"%s.out",s);
  //	freopen(str,"w",stdout);
#endif
}
inline int rd() {
  static int x, f;
  x = 0;
  f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return f > 0 ? x : -x;
}
const int N = 410, mod = 998244353;
int n, a[N], b[N], SA, SB;
int f[2][N][N], rfac[N];
int pw[N][N];

inline int pls(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
inline int upd(int &a, int b) { return a = pls(a, b); }
inline int mns(int a, int b) { return a < b ? a - b + mod : a - b; }
inline int mul(int a, int b) { return (ll)a * b % mod; }
inline int pwr(int x, int k) {
  int res = 1;
  for (; k; k >>= 1, x = mul(x, x))
    if (k & 1)
      res = mul(res, x);
  return res;
}

int main() {
  open("hh");
  n = rd();
  fo(i, 1, n) {
    a[i] = rd(), b[i] = rd();
    SA += a[i];
    SB += b[i];
  }
  rfac[0] = rfac[1] = 1;
  fo(i, 2, 400) rfac[i] = mns(0, mul(mod / i, rfac[mod % i]));
  fo(i, 2, 400) rfac[i] = mul(rfac[i - 1], rfac[i]);
  fo(i, 0, 400) fo(j, 0, 401) pw[i][j] = pwr(i, j);
  int u = 0, v = 1;
  f[0][0][0] = mod - 1;
  fo(i, 1, n) {
    fo(j, 0, SA) fo(k, 0, SB) if (f[u][j][k]) {
      int tmp = f[u][j][k];
      upd(f[v][j][k], tmp);
      tmp = mns(0, tmp);
      fo(l, 0, b[i] - 1) {
        int hh = mul(tmp, mul(pw[a[i]][l], rfac[l]));
        upd(f[v][j + a[i]][k + l], hh);
      }
    }
    swap(u, v);
    memset(f[v], 0, sizeof f[v]);
  }
  int ans = 0;
  fo(i, 1, SA) fo(j, 0, SB) {
    int tmp = f[u][i][j];
    //		if(tmp)cout<<i<<' '<<j<<' '<<tmp<<'\n';
    tmp = mul(tmp, pwr(i, mod - 2));
    tmp = mul(tmp, SA);
    tmp = mul(tmp, pwr(rfac[j], mod - 2));
    tmp = mul(tmp, pwr(pw[i][j], mod - 2));
    upd(ans, tmp);
  }
  cout << ans;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define of(i, l, r) for (int i = l; i >= r; i--)
#define fe(i, u) for (int i = head[u]; i; i = e[i].next)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
inline void open(const char *s) {
#ifndef ONLINE_JUDGE
  char str[20];
  sprintf(str, "%s.in", s);
  freopen(str, "r", stdin);
  //	sprintf(str,"%s.out",s);
  //	freopen(str,"w",stdout);
#endif
}
inline int rd() {
  static int x, f;
  x = 0;
  f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return f > 0 ? x : -x;
}
const int N = 410, mod = 998244353;
int n, a[N], b[N], SA, SB;
int f[2][N][N], rfac[N];
int pw[N][N];

inline int pls(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
inline int upd(int &a, int b) { return a = pls(a, b); }
inline int mns(int a, int b) { return a < b ? a - b + mod : a - b; }
inline int mul(int a, int b) { return (ll)a * b % mod; }
inline int pwr(int x, int k) {
  int res = 1;
  for (; k; k >>= 1, x = mul(x, x))
    if (k & 1)
      res = mul(res, x);
  return res;
}

int main() {
  n = rd();
  fo(i, 1, n) {
    a[i] = rd(), b[i] = rd();
    SA += a[i];
    SB += b[i];
  }
  rfac[0] = rfac[1] = 1;
  fo(i, 2, 400) rfac[i] = mns(0, mul(mod / i, rfac[mod % i]));
  fo(i, 2, 400) rfac[i] = mul(rfac[i - 1], rfac[i]);
  fo(i, 0, 400) fo(j, 0, 401) pw[i][j] = pwr(i, j);
  int u = 0, v = 1;
  f[0][0][0] = mod - 1;
  fo(i, 1, n) {
    fo(j, 0, SA) fo(k, 0, SB) if (f[u][j][k]) {
      int tmp = f[u][j][k];
      upd(f[v][j][k], tmp);
      tmp = mns(0, tmp);
      fo(l, 0, b[i] - 1) {
        int hh = mul(tmp, mul(pw[a[i]][l], rfac[l]));
        upd(f[v][j + a[i]][k + l], hh);
      }
    }
    swap(u, v);
    memset(f[v], 0, sizeof f[v]);
  }
  int ans = 0;
  fo(i, 1, SA) fo(j, 0, SB) {
    int tmp = f[u][i][j];
    //		if(tmp)cout<<i<<' '<<j<<' '<<tmp<<'\n';
    tmp = mul(tmp, pwr(i, mod - 2));
    tmp = mul(tmp, SA);
    tmp = mul(tmp, pwr(rfac[j], mod - 2));
    tmp = mul(tmp, pwr(pw[i][j], mod - 2));
    upd(ans, tmp);
  }
  cout << ans;
  return 0;
}