Topic Portal
Title Description
A tree of n nodes, each node provided it is $ v_1, v_2, ..., v_n $, known in the i-th node degree is $ V_I $ $ $ D_i, Q satisfying such a condition different how many trees trees. Given n, $ d_1, d_2, ..., d_n $, the programming required to meet the number of output $ d_ {v_i} = d_i $ tree.
Input Format
The first line is a positive integer n, the tree has n nodes. The second row has the number n, denotes the i-th $ d_i $, i.e. the i-th tree node degree.
Output Format
Output to meet the conditions of the tree how many trees.
Sample
Sample input
4
2 1 2 1
Sample Output
2
Data range and tips
$1 \leqslant n \leqslant 150$。
Ensure that the input data satisfies the condition of the tree does not exceed $ ^ {10} {17} $ a.
answer
The board is clearly a problem prufer sequence, the degree n points are determined for $ d_1, d_2, ... $ root of the tree no number: $ \ frac {(d_1-1) {(n-2)!} ! \ times (d_2-1)! \ times ...} $
However, note that two special sentence:
1. To satisfy the tree is a $ \ sum \ limits_ {i = 1} ^ {n} d_i = 2 \ times n-2 $.
2. When $ n = 1 $ obviously inconvenient to handle, can be directly output 1.
Direct output "0" you will be pleasantly surprised to find that you have 15 minutes!
As for the implementation, a high refinement for violence may be used, of course, also possible to use decomposition of the quality factor, the latter apparently achieved better.
Code time
#include<bits/stdc++.h>
using namespace std;
int n;
int d[151];
int pre[400],pri[400];
long long wzc[400];
long long ans=1LL;
void pre_work()//预处理质因数
{
for(int i=2;i<=2*n;i++)
{
if(!pri[i])
{
pri[i]=i;
pre[++pre[0]]=i;
}
for(int j=1;j<=pre[0];j++)
{
if(pre[j]>pri[i]||i*pre[j]>n)break;
pri[i*pre[j]]=pre[j];
}
}
}
long long qsm(long long x,long long y)
{
long long rec=1;
while(y)
{
if(y&1)rec*=x;
x*=x;
y>>=1;
}
return rec;
}
int main()
{
scanf("%d",&n);
pre_work();
int sum=0;
bool flag=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&d[i]);
if(!d[i])flag=1;
sum+=d[i];
}
if(n==1&&!d[1]){puts("1");return 0;}
if(sum!=2*n-2||flag){puts("0");return 0;}//两个特判
for(int i=1;i<=n-2;i++)
{
int flag=i;
while(flag>1)
{
wzc[pri[flag]]++;
flag/=pri[flag];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<d[i];j++)
{
int flag=j;
while(flag>1)
{
wzc[pri[flag]]--;
flag/=pri[flag];
}
}
}
for(int i=1;i<=n;i++)
if(wzc[i])ans=ans*qsm(i,wzc[i]);//计算答案
printf("%lld",ans);
return 0;
}
rp ++