Problem p03492 (C++)

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

typedef long long ll;
typedef unsigned long long ull;

using namespace std;

const int MAXN = 1E4 + 10;
const int P = 1E9 + 7;

template <typename T1, typename T2> void Inc(T1 &a, T2 b) {
  a += b;
  if (a >= P)
    a -= P;
}

template <typename T1, typename T2> void Dec(T1 &a, T2 b) {
  a -= b;
  if (a < 0)
    a += P;
}

template <typename T1, typename T2> T1 Add(T1 a, T2 b) {
  a += b;
  return a >= P ? a - P : a;
}

template <typename T1, typename T2> T1 Sub(T1 a, T2 b) {
  a -= b;
  return a < 0 ? a + P : a;
}

ll ksm(ll a, ll b) {
  ll ret = 1;
  for (; b; b >>= 1, (a *= a) %= P)
    if (b & 1)
      (ret *= a) %= P;
  return ret;
}

int n, siz[MAXN], rt, mxrt;
vector<int> T[MAXN];
ll fac[MAXN], ifac[MAXN], f[2][MAXN];

ll C(int n, int m) { return fac[n] * ifac[n - m] % P * ifac[m] % P; }

ll A(int n, int m) { return fac[n] * ifac[n - m] % P; }

void find_rt(int x, int fa) {
  siz[x] = 1;
  int mx = 0;
  for (int v : T[x])
    if (v != fa) {
      find_rt(v, x);
      siz[x] += siz[v];
      mx = max(mx, siz[v]);
    }
  mx = max(mx, n - siz[x]);
  if (mx < mxrt)
    mxrt = mx, rt = x;
}

int main() {
  scanf("%d", &n);
  for (int i = 1, u, v; i < n; i++)
    scanf("%d%d", &u, &v), T[u].push_back(v), T[v].push_back(u);
  fac[0] = ifac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = fac[i - 1] * i % P;
  ifac[n] = ksm(fac[n], P - 2);
  for (int i = n - 1; i; i--)
    ifac[i] = ifac[i + 1] * (i + 1) % P;
  mxrt = 1 << 30;
  find_rt(1, 0);
  if (~n & 1 && mxrt == n / 2)
    return printf("%lld\n", fac[n / 2] * fac[n / 2] % P);
  find_rt(rt, 0);
  int lst = 0;
  f[lst][0] = 1;
  for (int v : T[rt]) {
    memcpy(f[!lst], f[lst], sizeof f[!lst]);
    for (int i = 0; i <= n; i++)
      for (int j = 1; j <= siz[v] && i + j <= n; j++)
        Inc(f[!lst][i + j], f[lst][i] * A(siz[v], j) % P * C(siz[v], j) % P);
    lst ^= 1;
  }
  ll Ans = 0;
  for (int i = 0; i <= n; i++) {
    if (i & 1)
      Dec(Ans, f[lst][i] * fac[n - i] % P);
    else
      Inc(Ans, f[lst][i] * fac[n - i] % P);
  }
  printf("%lld\n", Ans);
}


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

typedef long long ll;
typedef unsigned long long ull;

using namespace std;

const int MAXN = 1E4 + 10;
const int P = 1E9 + 7;

template <typename T1, typename T2> void Inc(T1 &a, T2 b) {
  a += b;
  if (a >= P)
    a -= P;
}

template <typename T1, typename T2> void Dec(T1 &a, T2 b) {
  a -= b;
  if (a < 0)
    a += P;
}

template <typename T1, typename T2> T1 Add(T1 a, T2 b) {
  a += b;
  return a >= P ? a - P : a;
}

template <typename T1, typename T2> T1 Sub(T1 a, T2 b) {
  a -= b;
  return a < 0 ? a + P : a;
}

ll ksm(ll a, ll b) {
  ll ret = 1;
  for (; b; b >>= 1, (a *= a) %= P)
    if (b & 1)
      (ret *= a) %= P;
  return ret;
}

int n, siz[MAXN], rt, mxrt;
vector<int> T[MAXN];
ll fac[MAXN], ifac[MAXN], f[2][MAXN];

ll C(int n, int m) { return fac[n] * ifac[n - m] % P * ifac[m] % P; }

ll A(int n, int m) { return fac[n] * ifac[n - m] % P; }

void find_rt(int x, int fa) {
  siz[x] = 1;
  int mx = 0;
  for (int v : T[x])
    if (v != fa) {
      find_rt(v, x);
      siz[x] += siz[v];
      mx = max(mx, siz[v]);
    }
  mx = max(mx, n - siz[x]);
  if (mx < mxrt)
    mxrt = mx, rt = x;
}

int main() {
  scanf("%d", &n);
  for (int i = 1, u, v; i < n; i++)
    scanf("%d%d", &u, &v), T[u].push_back(v), T[v].push_back(u);
  fac[0] = ifac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = fac[i - 1] * i % P;
  ifac[n] = ksm(fac[n], P - 2);
  for (int i = n - 1; i; i--)
    ifac[i] = ifac[i + 1] * (i + 1) % P;
  mxrt = 1 << 30;
  find_rt(1, 0);
  if (~n & 1 && mxrt == n / 2)
    return printf("%lld\n", fac[n / 2] * fac[n / 2] % P), 0;
  find_rt(rt, 0);
  int lst = 0;
  f[lst][0] = 1;
  for (int v : T[rt]) {
    memcpy(f[!lst], f[lst], sizeof f[!lst]);
    for (int i = 0; i <= n; i++)
      for (int j = 1; j <= siz[v] && i + j <= n; j++)
        Inc(f[!lst][i + j], f[lst][i] * A(siz[v], j) % P * C(siz[v], j) % P);
    lst ^= 1;
  }
  ll Ans = 0;
  for (int i = 0; i <= n; i++) {
    if (i & 1)
      Dec(Ans, f[lst][i] * fac[n - i] % P);
    else
      Inc(Ans, f[lst][i] * fac[n - i] % P);
  }
  printf("%lld\n", Ans);
}