【bzoj1211】 [HNOI2004]树的计数

来源:互联网 发布:土耳其进行曲 知乎 编辑:程序博客网 时间:2024/06/04 20:12

Description

一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵。给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di的树的个数。

Input

第一行是一个正整数n,表示树有n个结点。第二行有n个数,第i个数表示di,即树的第i个结点的度数。其中1<=n<=150,输入数据保证满足条件的树不超过10^17个。

Output

输出满足条件的树有多少棵。

Sample Input

4

2 1 2 1

Sample Output

2

题解
同1005,略有区别。

代码

#include<bits/stdc++.h>#define N 1005#define ll long long#define mo 1000000007using namespace std;bool mark[1005];int n,a[1005],ans[1000005],len;int pri[1005],sum,tot,cnt,d[1005];inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}void get_pri(){    for (int i=2;i<=1000;i++)    {        if (!mark[i]) pri[++tot]=i;        for (int j=1;j<=tot&&i*pri[j]<=1000;j++)        {            mark[i*pri[j]]=0;            if (i%pri[j]==0) break;        }    }}void modify(int x,int f){    for (int k=2;k<=x;k++)    {        int t=k;        for (int i=1;i<=tot&&pri[i]<=k;i++)        {            if (t<=1) break;            int num=0;            while (t%pri[i]==0)            {                num++;                t/=pri[i];            }            a[i]+=f*num;        }    }}void mul(int x){    int z=0;    for (int i=1;i<=len;i++)    {        ans[i]=ans[i]*x+z;        z=ans[i]/10;        ans[i]%=10;    }    if (z)    {        while (z)        {            len++;            ans[len]=z%10;            z/=10;        }    }}int main(){    n=read();    if (n==1)    {        int x=read();        if (x==0) puts("1");        else puts("0");        return 0;     }    get_pri();    for (int i=1;i<=n;i++)    {        int x=read();        if (x==0){puts("0");return 0;}        if (x!=-1)        {            cnt++;            d[cnt]=--x;            sum+=x;        }    }    if (sum!=n-2){puts("0");return 0;}    modify(n-2,1);modify(n-2-sum,-1);    for (int i=1;i<=cnt;i++)        modify(d[i],-1);    int x=n-cnt;    for (int i=1;i<=tot&&pri[i]<=x;i++)    {        if (x<=1) break;        int num=0;        while (x%pri[i]==0)        {            num++;            x/=pri[i];        }        a[i]+=num*(n-2-sum);    }    len=1;ans[1]=1;    for (int i=1;i<=tot;i++)    {        for (int j=1;j<=a[i];j++)            mul(pri[i]);    }    for (int i=len;i;i--) printf("%d",ans[i]);    puts("");    return 0;}
原创粉丝点击