Problem p03991 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

inline int read() {
  int x = 0;
  char ch = getchar();
  while (ch < '0' || '9' < ch)
    ch = getchar();
  while ('0' <= ch && ch <= '9')
    x = x * 10 + (ch ^ 48), ch = getchar();
  return x;
}

typedef long long ll;
const int N = 200009;
const ll md = 924844033;

int n, m, l;
int to[N << 1], nxt[N << 1], beg[N], tot;
int rev[N << 1], siz[N];
ll a[N << 1], b[N << 1], fac[N], inv[N];

inline void chk(ll &a) {
  if (a < 0)
    a += md;
}

inline ll qpow(ll a, ll b) {
  ll ret = 1ll;
  while (b) {
    if (b & 1ll)
      ret = ret * a % md;
    a = a * a % md;
    b >>= 1;
  }
  return ret;
}

inline void add(int u, int v) {
  to[++tot] = v;
  nxt[tot] = beg[u];
  beg[u] = tot;
}

inline void dfs(int u, int fa) {
  a[n]++;
  siz[u] = 1;
  for (int i = beg[u]; i; i = nxt[i])
    if (to[i] != fa) {
      dfs(to[i], u);
      siz[u] += siz[to[i]];
      chk(--a[siz[to[i]]]);
    }
  chk(--a[n - siz[u]]);
}

inline void NTT(ll *a, int n, bool f) {
  for (int i = 0; i < n; i++)
    if (i < rev[i])
      swap(a[i], a[rev[i]]);
  for (int h = 2; h <= n; h <<= 1) {
    ll w = qpow(5, (md - 1) / h);
    if (f)
      w = qpow(w, md - 2);
    for (int j = 0; j < n; j += h) {
      ll wn = 1;
      for (int k = j; k < j + (h >> 1); k++) {
        ll x = a[k], y = wn * a[k + (h >> 1)] % md;
        a[k] = (x + y) % md;
        a[k + (h >> 1)] = (x - y + md) % md;
        wn = wn * w % md;
      }
    }
  }

  if (f)
    for (ll i = 0, invn = qpow(n, md - 2); i < n; i++)
      a[i] = a[i] * invn % md;
}

inline void init() {
  fac[0] = 1;
  for (ll i = 1; i < N; i++)
    fac[i] = fac[i - 1] * i % md;
  inv[N - 1] = qpow(fac[N - 1], md - 2);
  for (ll i = N - 1; i >= 1; i--)
    inv[i - 1] = inv[i] * i % md;
}

int main() {
  if (fopen("vj.in", "r")) {
    freopen("vj.in", "r", stdin);
    freopen("vj.out", "w", stdout);
  }

  init();
  n = read();
  for (int i = 1, u, v; i < n; i++) {
    u = read();
    v = read();
    add(u, v);
    add(v, u);
  }
  dfs(1, 1);

  for (int i = 1; i <= n; i++)
    a[i] = a[i] * fac[i] % md;
  for (int i = 1; i <= n; i++)
    b[i] = inv[n - i];

  for (m = 1, l = 0; m <= (n << 1); m <<= 1)
    l++;
  for (int i = 0; i < m; i++)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1));

  NTT(a, m, 0);
  NTT(b, m, 0);
  for (int i = 0; i < m; i++)
    a[i] = a[i] * b[i] % md;
  NTT(a, m, 1);

  for (int i = 1; i <= n; i++)
    printf("%lld\n", a[n + i] * inv[i] % md);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

inline int read() {
  int x = 0;
  char ch = getchar();
  while (ch < '0' || '9' < ch)
    ch = getchar();
  while ('0' <= ch && ch <= '9')
    x = x * 10 + (ch ^ 48), ch = getchar();
  return x;
}

typedef long long ll;
const int N = 400009;
const ll md = 924844033;

int n, m, l;
int to[N << 1], nxt[N << 1], beg[N], tot;
int rev[N << 1], siz[N];
ll a[N << 1], b[N << 1], fac[N], inv[N];

inline void chk(ll &a) {
  if (a < 0)
    a += md;
}

inline ll qpow(ll a, ll b) {
  ll ret = 1ll;
  while (b) {
    if (b & 1ll)
      ret = ret * a % md;
    a = a * a % md;
    b >>= 1;
  }
  return ret;
}

inline void add(int u, int v) {
  to[++tot] = v;
  nxt[tot] = beg[u];
  beg[u] = tot;
}

inline void dfs(int u, int fa) {
  a[n]++;
  siz[u] = 1;
  for (int i = beg[u]; i; i = nxt[i])
    if (to[i] != fa) {
      dfs(to[i], u);
      siz[u] += siz[to[i]];
      chk(--a[siz[to[i]]]);
    }
  chk(--a[n - siz[u]]);
}

inline void NTT(ll *a, int n, bool f) {
  for (int i = 0; i < n; i++)
    if (i < rev[i])
      swap(a[i], a[rev[i]]);
  for (int h = 2; h <= n; h <<= 1) {
    ll w = qpow(5, (md - 1) / h);
    if (f)
      w = qpow(w, md - 2);
    for (int j = 0; j < n; j += h) {
      ll wn = 1;
      for (int k = j; k < j + (h >> 1); k++) {
        ll x = a[k], y = wn * a[k + (h >> 1)] % md;
        a[k] = (x + y) % md;
        a[k + (h >> 1)] = (x - y + md) % md;
        wn = wn * w % md;
      }
    }
  }

  if (f)
    for (ll i = 0, invn = qpow(n, md - 2); i < n; i++)
      a[i] = a[i] * invn % md;
}

inline void init() {
  fac[0] = 1;
  for (ll i = 1; i < N; i++)
    fac[i] = fac[i - 1] * i % md;
  inv[N - 1] = qpow(fac[N - 1], md - 2);
  for (ll i = N - 1; i >= 1; i--)
    inv[i - 1] = inv[i] * i % md;
}

int main() {
  if (fopen("vj.in", "r")) {
    freopen("vj.in", "r", stdin);
    freopen("vj.out", "w", stdout);
  }

  init();
  n = read();
  for (int i = 1, u, v; i < n; i++) {
    u = read();
    v = read();
    add(u, v);
    add(v, u);
  }
  dfs(1, 1);

  for (int i = 1; i <= n; i++)
    a[i] = a[i] * fac[i] % md;
  for (int i = 1; i <= n; i++)
    b[i] = inv[n - i];

  for (m = 1, l = 0; m <= (n << 1); m <<= 1)
    l++;
  for (int i = 0; i < m; i++)
    rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (l - 1));

  NTT(a, m, 0);
  NTT(b, m, 0);
  for (int i = 0; i < m; i++)
    a[i] = a[i] * b[i] % md;
  NTT(a, m, 1);

  for (int i = 1; i <= n; i++)
    printf("%lld\n", a[n + i] * inv[i] % md);
  return 0;
}