Description
自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
Input
第一行为N(0 < N < = 1000),
接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
Output
一个整数,表示不同的满足要求的树的个数,无解输出0
Sample Input
3
1
-1
-1
1
-1
-1
Sample Output
2
HINT
两棵树分别为1-2-3;1-3-2
Solution
要写高精度和质因数分解。
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N (3009)
#define MAX_L 10009
using namespace std; int n,m,rem,d,ans[N],cnt[N]; void Divide(int x,int opt)
{
for (int i=; i<=sqrt(x); ++i)
while (x%i==) x/=i,cnt[i]+=opt;
if (x>) cnt[x]+=opt;
} void Mul(int *a,int b)
{
int g=;
for (int i=; i<=a[]; ++i)
a[i]=a[i]*b+g,g=a[i]/,a[i]%=;
while (g) a[]++,a[a[]]=g%,g/=;
} int main()
{
ans[]=ans[]=;
scanf("%d",&n); rem=n-;
for (int i=; i<=n-; ++i) Divide(i,);
for (int i=; i<=n; ++i)
{
scanf("%d",&d);
if (!d && n>) {puts(""); return ;}
if (d==-) {++m; continue;}
if ((rem=rem-(d-))<) {puts(""); return ;}
for (int j=; j<=d-; ++j) Divide(j,-);
}
if (n==)
{
if (d==- || d==) puts("");
else puts("");
return ;
}
for (int i=; i<=rem; ++i) Divide(i,-);
for (int i=; i<=rem; ++i) Divide(m,);
for (int i=; i<=n; ++i)
for (int j=; j<=cnt[i]; ++j)
Mul(ans,i);
for (int i=ans[]; i>=; --i)
printf("%d",ans[i]);
}