Problem p03991 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

template <int N, int MOD> struct NTT {
  void transform(int n, int *a) {
    for (int m = 1; m < n; m <<= 1) {
      int64_t root = power(G, (MOD - 1) / (m << 1));
      twiddles[0] = 1;
      for (int i = 1; i < m; ++i) {
        twiddles[i] = twiddles[i - 1] * root % MOD;
      }
      for (int i = 0; i < n; i += m << 1) {
        for (int r = i; r < i + m; ++r) {
          int tmp = static_cast<int64_t>(twiddles[r - i]) * a[r + m] % MOD;
          a[r + m] = a[r];
          add(a[r + m], MOD - tmp);
          add(a[r], tmp);
        }
      }
    }
  }

  void itransform(int n, int *a) {
    for (int m = n; m >>= 1;) {
      int64_t root = power(G, MOD - 1 - (MOD - 1) / (m << 1));
      twiddles[0] = 1;
      for (int i = 1; i < m; ++i) {
        twiddles[i] = twiddles[i - 1] * root % MOD;
      }
      for (int i = 0; i < n; i += m << 1) {
        for (int r = i; r < i + m; ++r) {
          int tmp = a[r];
          add(tmp, MOD - a[r + m]);
          add(a[r], a[r + m]);
          a[r + m] = static_cast<int64_t>(twiddles[r - i]) * tmp % MOD;
        }
      }
    }
  }

  void convolute(int n, int *a, int *b, int *out) {
    itransform(n, a);
    itransform(n, b);
    int64_t inv_n = power(n, MOD - 2);
    for (int i = 0; i < n; ++i) {
      out[i] = inv_n * a[i] % MOD * b[i] % MOD;
    }
    transform(n, out);
  }

private:
  static constexpr int power(int a, int n) {
    int res = 1;
    while (n) {
      if (n & 1) {
        res = 1ULL * res * a % MOD;
      }
      a = 1ULL * a * a % MOD;
      n >>= 1;
    }
    return res;
  }

  static void add(int &x, int a) {
    x += a;
    if (x >= MOD) {
      x -= MOD;
    }
  }

  static void prepare_roots(int n, int *roots, int g) {
    roots[0] = 1;
    for (int i = 1; i < n; ++i) {
      roots[i] = static_cast<int64_t>(roots[i - 1]) * g % MOD;
    }
  }

  struct FiniteField {
    static constexpr int primitive_root() {
      int g = 2;
      while (!is_primitive_root(g)) {
        g++;
      }
      return g;
    }

  private:
    static constexpr bool is_primitive_root(int g) {
      for (int d = 2; d * d <= MOD - 1; ++d) {
        if ((MOD - 1) % d == 0 &&
            (power(g, d) == 1 || power(g, (MOD - 1) / d) == 1)) {
          return false;
        }
      }
      return true;
    }
  };

  static const int G = FiniteField::primitive_root();
  int twiddles[N];
};

const int N = 200001;
const int MOD = 924844033;

int n, count[N], out[N], ifact[N];
std::vector<int> tree[N];
NTT<N, MOD> ntt;

void add(int &x, int a) {
  x += a;
  if (x >= MOD) {
    x -= MOD;
  }
}

int inv(int a) {
  return a == 1 ? 1 : static_cast<int64_t>(MOD - MOD / a) * inv(MOD % a) % MOD;
}

int dfs(int p, int u) {
  int size = 1;
  for (int v : tree[u]) {
    if (v != p) {
      int subsize = dfs(u, v);
      add(count[subsize], MOD - 1);
      add(count[n - subsize], MOD - 1);
      size += subsize;
    }
  }
  return size;
}

int main() {
  scanf("%d", &n);
  for (int i = 0, a, b; i < n - 1; ++i) {
    scanf("%d%d", &a, &b);
    a--, b--;
    tree[a].push_back(b);
    tree[b].push_back(a);
  }
  count[n] += n;
  dfs(-1, 0);
  int64_t fact = 1;
  for (int i = 0; i <= n; ++i) {
    if (i) {
      fact = fact * i % MOD;
    }
    out[n - i] = ifact[i] = inv(fact);
    count[i] = count[i] * fact % MOD;
  }
  int n2 = 1;
  while (n + n >= n2) {
    n2 <<= 1;
  }
  ntt.convolute(n2, count, out, out);
  for (int i = 1; i <= n; ++i) {
    printf("%ld\n", static_cast<int64_t>(out[n + i]) * ifact[i] % MOD);
  }
}

Fixed submission:
#include <bits/stdc++.h>

template <int N, int MOD> struct NTT {
  void transform(int n, int *a) {
    for (int m = 1; m < n; m <<= 1) {
      int64_t root = power(G, (MOD - 1) / (m << 1));
      twiddles[0] = 1;
      for (int i = 1; i < m; ++i) {
        twiddles[i] = twiddles[i - 1] * root % MOD;
      }
      for (int i = 0; i < n; i += m << 1) {
        for (int r = i; r < i + m; ++r) {
          int tmp = static_cast<int64_t>(twiddles[r - i]) * a[r + m] % MOD;
          a[r + m] = a[r];
          add(a[r + m], MOD - tmp);
          add(a[r], tmp);
        }
      }
    }
  }

  void itransform(int n, int *a) {
    for (int m = n; m >>= 1;) {
      int64_t root = power(G, MOD - 1 - (MOD - 1) / (m << 1));
      twiddles[0] = 1;
      for (int i = 1; i < m; ++i) {
        twiddles[i] = twiddles[i - 1] * root % MOD;
      }
      for (int i = 0; i < n; i += m << 1) {
        for (int r = i; r < i + m; ++r) {
          int tmp = a[r];
          add(tmp, MOD - a[r + m]);
          add(a[r], a[r + m]);
          a[r + m] = static_cast<int64_t>(twiddles[r - i]) * tmp % MOD;
        }
      }
    }
  }

  void convolute(int n, int *a, int *b, int *out) {
    itransform(n, a);
    itransform(n, b);
    int64_t inv_n = power(n, MOD - 2);
    for (int i = 0; i < n; ++i) {
      out[i] = inv_n * a[i] % MOD * b[i] % MOD;
    }
    transform(n, out);
  }

private:
  static constexpr int power(int a, int n) {
    int res = 1;
    while (n) {
      if (n & 1) {
        res = 1ULL * res * a % MOD;
      }
      a = 1ULL * a * a % MOD;
      n >>= 1;
    }
    return res;
  }

  static void add(int &x, int a) {
    x += a;
    if (x >= MOD) {
      x -= MOD;
    }
  }

  static void prepare_roots(int n, int *roots, int g) {
    roots[0] = 1;
    for (int i = 1; i < n; ++i) {
      roots[i] = static_cast<int64_t>(roots[i - 1]) * g % MOD;
    }
  }

  struct FiniteField {
    static constexpr int primitive_root() {
      int g = 2;
      while (!is_primitive_root(g)) {
        g++;
      }
      return g;
    }

  private:
    static constexpr bool is_primitive_root(int g) {
      for (int d = 2; d * d <= MOD - 1; ++d) {
        if ((MOD - 1) % d == 0 &&
            (power(g, d) == 1 || power(g, (MOD - 1) / d) == 1)) {
          return false;
        }
      }
      return true;
    }
  };

  static const int G = FiniteField::primitive_root();
  int twiddles[N];
};

const int N = 1 << 19;
const int MOD = 924844033;

int n, count[N], out[N], ifact[N];
std::vector<int> tree[N];
NTT<N, MOD> ntt;

void add(int &x, int a) {
  x += a;
  if (x >= MOD) {
    x -= MOD;
  }
}

int inv(int a) {
  return a == 1 ? 1 : static_cast<int64_t>(MOD - MOD / a) * inv(MOD % a) % MOD;
}

int dfs(int p, int u) {
  int size = 1;
  for (int v : tree[u]) {
    if (v != p) {
      int subsize = dfs(u, v);
      add(count[subsize], MOD - 1);
      add(count[n - subsize], MOD - 1);
      size += subsize;
    }
  }
  return size;
}

int main() {
  scanf("%d", &n);
  for (int i = 0, a, b; i < n - 1; ++i) {
    scanf("%d%d", &a, &b);
    a--, b--;
    tree[a].push_back(b);
    tree[b].push_back(a);
  }
  count[n] += n;
  dfs(-1, 0);
  int64_t fact = 1;
  for (int i = 0; i <= n; ++i) {
    if (i) {
      fact = fact * i % MOD;
    }
    out[n - i] = ifact[i] = inv(fact);
    count[i] = count[i] * fact % MOD;
  }
  int n2 = 1;
  while (n + n >= n2) {
    n2 <<= 1;
  }
  ntt.convolute(n2, count, out, out);
  for (int i = 1; i <= n; ++i) {
    printf("%ld\n", static_cast<int64_t>(out[n + i]) * ifact[i] % MOD);
  }
}