组合数进阶篇vijos1137组合数
Posted qin-wei-kai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合数进阶篇vijos1137组合数相关的知识,希望对你有一定的参考价值。
描述
组合公式 C=N!/(M!*(N-M)!). 问题是求 C 中不同的质因子的个数
例如 N=7, M=4. C=7!/(3!*4!)=5040/(6*24)=35=5*7. 则不同的质因子的个数为2 (分别是5,7)。
格式
输入格式
输入N,M
输出格式
输出一个整数
样例1
样例输入1
7 4
样例输出1
2
限制
1s
数据规模没有给出来 [vijos: 可能是1<=M<=N<=100,000]
提示
注意观察一下组合数的性质呀!!
这道题主要的思路就是,把分子和分母质因数分解,然后进行指数相加减(肯定不能出负数),因为分子分母肯定可以约分的,复杂度是n根号n,因为n最大,要筛质数
还是比较好理解的,我用的n-m+1到n,这样会快一丢丢
上代码
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n,m,cnt,ans; 6 int pri[100011],ct[100011]; 7 bool vis[100011]; 8 void make_pri(int n) 9 { 10 for(int i=2;i<=n;i++) 11 { 12 if(!vis[i])pri[++cnt]=i; 13 for(int j=1;j<=cnt && i*pri[j]<=n;j++) 14 { 15 vis[i*pri[j]]=1; 16 if(!i%pri[j])break; 17 } 18 } 19 } 20 int main() 21 { 22 scanf("%d%d",&n,&m); 23 make_pri(n); 24 for(int i=n-m+1;i<=n;i++) 25 { 26 int tt=i; 27 for(int j=1;j<=cnt&&tt;j++) 28 { 29 while(!(tt%pri[j])) 30 ct[j]++,tt/=pri[j]; 31 } 32 } 33 for(int i=1;i<=m;i++) 34 { 35 int tt=i; 36 for(int j=1;j<=cnt&&tt;j++) 37 { 38 while(!(tt%pri[j])) 39 ct[j]--,tt/=pri[j]; 40 } 41 } 42 for(int i=1;i<=cnt;i++) 43 if(ct[i]) 44 ans++; 45 printf("%d",ans); 46 return 0; 47 }
以上是关于组合数进阶篇vijos1137组合数的主要内容,如果未能解决你的问题,请参考以下文章
组合数问题 vijos2006 NOIP2016 D2T1 杨辉三角 排列组合 前缀和