Description

自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?

Input

第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1

Output

一个整数,表示不同的满足要求的树的个数,无解输出0

Sample Input

3
1
-1
-1

Sample Output

2

HINT

两棵树分别为1-2-3;1-3-2

 
数学相关
我觉得我是做不出来了,只能学一下关于暴力分解的各种咯
 #include<cstdio>
#define mod 100000
#include<cmath>
using namespace std;
int num[],ans[],pri[],d[];
int cnt,n,l,m,tot;
bool jud(int x){
for(int i=;i<=sqrt(x);i++)
if(x%i==)return ;
return ;
} void getpri(){
for(int i=;i<=;i++)
if(jud(i))pri[++cnt]=i;
} void solve(int a,int f){
for(int i=;i<=a;i++){
int x=i;
for(int j=;j<=cnt;j++){
if(x==) break;
while(x%pri[j]==){
num[j]+=f;x/=pri[j];
}
}
}
} void mult(int x){
for(int i=;i<=l;i++) ans[i]*=x;
for(int i=;i<=l;i++) ans[i+]+=ans[i]/mod,ans[i]%=mod;
while(ans[l+]>){
l++;ans[l+]=ans[l]/mod;ans[l]%=mod;
}
}
void print()
{
for(int i=l;i>;i--)
if(i==l)printf("%d",ans[i]);
else printf("%05d",ans[i]);
}
int main(){
getpri();
int x;ans[]=;l=;
scanf("%d",&n);
if(n==){
scanf("%d",&x);
if(!x) {printf("");return ;}
else {printf("");return ;}
}
for(int i=;i<=n;i++){
scanf("%d",&d[i]);
if(d[i]==) {printf("");return ;}
if(d[i]==-) m++;
else {d[i]--;tot+=d[i];}
}
if(tot>n-){printf("");return ;}
solve(n-,);solve(n--tot,-);
for(int i=;i<=n;i++) if(d[i]) solve(d[i],-);
for(int i=;i<=n--tot;i++) mult(m);
for(int i=;i<=cnt;i++) while(num[i]--) mult(pri[i]);
print();
}
05-04 04:53