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
- vijosP1388 二叉树数
- 二叉排序数树
- 树与二叉数
- 二叉数||AVL树
- 【二叉搜索数】HDU3791二叉搜索树
- 二叉树双分支数
- 二叉树所有分支数
- 二叉树求叶子数
- 完全二叉树节点数
- 完全二叉树节点数
- 完全二叉树结点数
- 树-A- 二叉数应用
- 数转化为二叉树
- 二叉数
- 二叉数
- 二叉数
- 二叉树(3):对二叉树数的操作
- 二叉树的实现和二叉数的遍历实现
- vijosP1092 全排列
- vijosP1289 老板娘的促销方案
- vijosP1413 Valentine’s Present
- HTTPS学习(一):工作过程
- vijosP1371 方程的解
- vijosP1388 二叉树数
- vijosP1687 细菌总数
- 自定义ZbarView
- vijosP1629 八
- BZOJ1008 [HNOI2008]越狱
- 洛谷1349 广义斐波那契数列 【矩阵乘法】
- 洛谷1076 寻宝
- BZOJ2705 [SDOI2012]Longge的问题
- 洛谷P1407 工资