[bzoj1005]明明的烦恼

根据purfer序列的原理,每一个purfer序列都一一对应了一棵树,每一个点在purfer序列中出现的次数就是它的度数,那么直接用组合数去计算即可,注意要加高精度

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 struct ji{
 5     int len,a[10001];
 6 }a;
 7 int n,m,k,d[1001],vis[1001];
 8 void cheng(int b){
 9     a.a[1]*=b;
10     for(int i=2;i<=a.len;i++){
11         a.a[i]=a.a[i]*b+a.a[i-1]/10;
12         a.a[i-1]%=10;
13     }
14     while (a.a[a.len]>9){
15         a.a[a.len+1]=a.a[a.len]/10;
16         a.a[a.len++]%=10;
17     }
18 }
19 void calc(int k,int p){
20     for(int i=2;i*i<=k;i++)
21         while (k%i==0){
22             vis[i]+=p;
23             k/=i;
24         }
25     if (k>1)vis[k]+=p;
26 }
27 void c(int a,int b){
28     for(int i=b+1;i<=a;i++)calc(i,1);
29     for(int i=1;i<=a-b;i++)calc(i,-1);
30 }
31 int main(){
32     scanf("%d",&n);
33     m=n-2;
34     k=n;
35     for(int i=1;i<=n;i++)scanf("%d",&d[i]);
36     a.len=a.a[1]=1;
37     for(int i=1;i<=n;i++)
38         if (d[i]!=-1){
39             c(m,d[i]-1);
40             m-=d[i]-1;
41             k--;
42         }
43     for(int i=1;i<=m;i++)calc(k,1);
44     for(int i=1;i<=1000;i++)
45         for(int j=1;j<=vis[i];j++)cheng(i);
46     for(int i=a.len;i;i--)printf("%d",a.a[i]);
47 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11846916.html