根据prufer序列可以一一对应无根树。
一个度数为(n)的会出现(n - 1)次,然后组合数算一算就好了。
注意高精度
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
int n, t;
const int MAXN = 5010;
typedef long long LL;
const int DX = 1000000;
struct N {
int sum[MAXN], dig;
void mul(int x) {
for (int i = 0; i != dig; ++i) sum[i] *= x;
for (int i = 0; i != dig + 5; ++i) {
sum[i + 1] += sum[i] / DX;
sum[i] %= DX;
}
dig += 5;
while (!sum[dig - 1]) --dig;
}
void div(int x) {
int now = 0;
for (int i = dig - 1; ~i; --i) {
now = now * DX + sum[i];
sum[i] = now / x;
now %= x;
}
while (!sum[dig - 1]) --dig;
}
void print() {
printf("%d", sum[dig - 1]);
for (int i = dig - 2; ~i; --i)
printf("%06d", sum[i]);
putchar(10);
}
} a;
int main() {
scanf("%d", &n);
a.sum[0] = 1; a.dig = 1;
for (int i = 2; i <= n - 2; ++i)
a.mul(i);
int lst = n - 2, cnt = 0;
for (int i = 1; i <= n; ++i) {
scanf("%d", &t);
cnt += t == -1;
if (t < 0) continue;
lst -= t - 1;
for (int j = t - 1; j > 1; --j)
a.div(j);
}
if (lst < 0 || (cnt == 0 && lst != 0)) return puts("0"), 0;
for (int i = 1; i <= lst; ++i) a.mul(cnt), a.div(i);
a.print();
return 0;
}