【组合数进阶篇】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 }
原文地址:https://www.cnblogs.com/Qin-Wei-Kai/p/10123765.html