bzoj1211: [HNOI2004]树的计数
2016-02-11 00:02
363 查看
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1211
题意:中文题。。。
分析:prufer序列计算树的种数,简单的应用。因为会爆int所以分解质因子就是了,注意处理树的合理性和n=1的情况。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<math.h> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=160; const int MAX=151; const int MOD1=100000007; const int MOD2=100000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=9999991; const ll INF=10000000010; typedef unsigned long long ull; int a ,bo ,p [6],q [6]; void deal() { int i,j,w,k=0,n=150; memset(bo,0,sizeof(bo)); bo[1]=1; for (i=2;i<=n;i++) { if (!bo[i]) a[++k]=i; for (j=1;j<=k;j++) { if (a[j]*i>n) break ; bo[a[j]*i]=1; if (i%a[j]==0) break ; } } memset(p,0,sizeof(p)); for (i=1;i<=k;i++) { w=a[i]; while (w<=n) { p[w][0]++;p[w][p[w][0]]=a[i];w+=a[i]; } } memset(q,0,sizeof(q)); for (i=1;i<=n;i++) { w=i; for (j=1;j<=p[i][0];j++) { while (w%p[i][j]==0) { q[i][j]++;w/=p[i][j]; } } } } int num ; void add(int x) { for (int i=1;i<=p[x][0];i++) num[p[x][i]]+=q[x][i]; } void sub(int x) { for (int i=1;i<=p[x][0];i++) num[p[x][i]]-=q[x][i]; } int main() { int i,j,n,x,w,sum=0,flge=0; ll ans=1; scanf("%d", &n); deal();w=n-2; memset(num,0,sizeof(num)); for (i=1;i<=n;i++) { scanf("%d", &x); sum+=x;x--; if (x<0) flge=1; if (!x) continue ; for (j=1;j<=x;j++) add(w-j+1); for (j=1;j<=x;j++) sub(j); w-=x; } if (n==1&&sum==0) { printf("1\n");return 0; } if (sum!=2*n-2||flge) { printf("0\n");return 0; } for (i=1;i<=150;i++) for (j=1;j<=num[i];j++) ans=ans*i; printf("%lld\n", ans); return 0; } /* 20 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 4 5 */
相关文章推荐