[BZOJ1005][HNOI2008]明明的烦恼 数学+prufer序列+高精度

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int N;
 6 int A[1010],D[1010],cnt=0;
 7 int sum=0,q=0;
 8 int pri[1010];
 9 int ans[100010],len;
10 int main(){
11     scanf("%d",&N);
12     if(N==1){
13         int tmp;
14         scanf("%d",&tmp);
15         if(!tmp||tmp==-1) puts("1");
16         else puts("0");
17         return 0;
18     }
19     for(int i=1;i<=N;i++){
20         scanf("%d",&A[i]);
21         if(!A[i]){
22             puts("0");
23             return 0;
24         }
25         if(A[i]!=-1){
26             D[++cnt]=A[i]-1;
27             sum+=D[cnt];
28         }
29         else q++;
30     }
31     if(N<sum+2){
32         puts("0");
33         return 0;
34     }
35     for(int i=1;i<=cnt;i++)
36         for(int j=2;j<=D[i];j++){
37             int tmp=j;
38             for(int k=2;k<=j&&tmp!=1;k++)
39                 while(tmp%k==0){
40                     pri[k]--;
41                     tmp/=k;
42                 }
43         }
44     for(int i=N-2-sum+1;i+2<=N;i++){
45         int tmp=i;
46         for(int j=2;j<=i&&tmp!=1;j++)
47             while(tmp%j==0){
48                 pri[j]++;
49                 tmp/=j;
50             }
51     }
52     ans[1]=1;
53     len=1;
54     for(int i=1;i<=N;i++){
55         while(pri[i]){
56             for(int j=1;j<=len;j++) ans[j]*=i;
57             for(int j=1;j<=len;j++){
58                 ans[j+1]+=ans[j]/10;
59                 ans[j]%=10;
60             }
61             while(ans[len+1]){
62                 len++;
63                 ans[len+1]+=ans[len]/10;
64                 ans[len]%=10;
65             }
66             pri[i]--;
67         }
68     }
69     for(int i=1;i+2+sum<=N;i++){
70         for(int j=1;j<=len;j++) ans[j]*=q;
71         for(int j=1;j<=len;j++){
72             ans[j+1]+=ans[j]/10;
73             ans[j]%=10;
74         }
75         while(ans[len+1]){
76             len++; 
77             ans[len+1]+=ans[len]/10;
78             ans[len]%=10;
79         }
80     }
81     for(int i=len;i>=1;i--) printf("%d",ans[i]);
82     return 0;
83 }

 

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1005

一个prufer序列可以唯一确定一棵生成树。而prufer序列可以确定节点的度数,反过来,通过度数就可以确定prufer序列的方案数。

具体怎么做贴个黄学长的题解接跑吧……

题解:http://hzwer.com/3272.html

 

posted @ 2017-10-04 20:51  halfrot  阅读(140)  评论(0编辑  收藏  举报