1. 程式人生 > >[BZOJ1005][HNOI2008]明明的煩惱 數學+prufer序列+高精度

[BZOJ1005][HNOI2008]明明的煩惱 數學+prufer序列+高精度

style pri 題解 line nbsp using code esp online

 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

[BZOJ1005][HNOI2008]明明的煩惱 數學+prufer序列+高精度