vijosP1388 二叉树数

来源:互联网 发布:苹果 app 办公软件 编辑:程序博客网 时间:2024/06/08 16:35
vijosP1388 二叉树数

 

链接:https://vijos.org/p/1388

 

【思路】

  Catalan数。根据公式h=C(2n,n)/(n+1)计算。首先化简为 (n+i)/i的积(1<=i<=n)

  法一:

高精单精乘除。

  法二:

唯一分解定理。将乘除操作转化为对质因子指数的加减,最后用高精单精乘起来。类于vijosP1137 组合数一题

 

 

【代码1】439ms

 

 

 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4  5 struct Bign { 6     int len; 7     long long N[10001]; 8     Bign() { 9         memset(N,0,sizeof(N));10     }11 };12 13 int n;14 15 void multi(Bign& a,int x)16 {17     for(int j=0;j<a.len;j++) a.N[j] *= x;18     int i=0;19     while(i<a.len || a.N[i]>10) {20         a.N[i+1] += a.N[i]/10;21         a.N[i] %= 10;22         i++;                    //i++23     }24     if(a.N[i]) a.len=i+1;  //判断25     else a.len=i;26 }27 28 void div(Bign& a,int x) {29     for(int i=a.len-1;i>0;i--) {  //由高位到低位30         a.N[i-1] += a.N[i]%x*10;31         a.N[i] /= x;32     }33     a.N[0]/=x;  //最后一位34     while(a.N[a.len-1]==0) a.len--;  //删除前导035 }36 37 int main() {38     cin>>n;39     Bign ans;40     ans.len=1; ans.N[0]=1;41     for(int i=1;i<=n;i++) {42         multi(ans,n+i);43         div(ans,i);44     }45     div(ans,n+1);46     for(int i=ans.len-1;i>=0;i--) cout<<ans.N[i];47     return 0; 48 }

 

 

【代码2】52ms

 

 1 #include<iostream> 2 #include<cstring> 3 #include<vector> 4 #include<cmath> 5 using namespace std; 6  7 const int maxn = 10000+10; 8 struct Bign{ 9     int len,N[maxn];10     Bign() {11         memset(N,0,sizeof(N));12     }13 };14 int e[maxn];15 int n,m,ans;16 vector<int> primes;17 18 void get_primes(int n) {19     bool su[maxn]; memset(su,true,sizeof(su));20     for(int i=2;i<=n;i++) if(su[i]) {21         primes.push_back(i);22         if(i<=sqrt(n)) for(int j=i*i;j<=n;j+=i) su[j]=false;23         //i<=sqrt(n) 否则RE 24     }25 }26 27 void calc(int x,int d) {28     for(int i=0;i<primes.size();i++) {29         while(x%primes[i]==0) {30             e[i] += d;31             x /= primes[i];32         }33         if(x==1) break;34     }35 }36 37 void multi(Bign& a,int x)38 {39     for(int j=0;j<a.len;j++) a.N[j] *= x;40     int i=0;41     while(i<a.len || a.N[i]>10) {42         a.N[i+1] += a.N[i]/10;43         a.N[i] %= 10;44         i++;                    //i++45     }46     if(a.N[i]) a.len=i+1;  //判断47     else a.len=i;48 }49 50 int main() {51     cin>>n;52     53     get_primes(2*n+1);54     55     for(int i=1;i<=n;i++) {56         calc(n+i,1);57         calc(i,-1);58     }59     calc(n+1,-1);60     Bign ans; ans.len=1; ans.N[0]=1;61     for(int i=0;i<primes.size();i++){62         while(e[i]--) multi(ans,primes[i]);63     }64     for(int i=ans.len-1;i>=0;i--) cout<<ans.N[i];65     return 0;66 }

 

0 0
原创粉丝点击