【思路】
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 }
时间: 2024-11-04 20:00:45