zoukankan      html  css  js  c++  java
  • vijosP1388 二叉树数

    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--;  //删除前导0
    35 }
    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 }
  • 相关阅读:
    POJ 3140 Contestants Division (树dp)
    POJ 3107 Godfather (树重心)
    POJ 1655 Balancing Act (树的重心)
    HDU 3534 Tree (经典树形dp)
    HDU 1561 The more, The Better (树形dp)
    HDU 1011 Starship Troopers (树dp)
    Light oj 1085
    Light oj 1013
    Light oj 1134
    FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4876480.html
Copyright © 2011-2022 走看看