组合数进阶篇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 杨辉三角 排列组合 前缀和

Vijos 连续数之和 (组合数学)

数论篇7——组合数 & 卢卡斯定理(Lucas)

组合数

leetcode 377. 组合总和 Ⅳ----动态规划之双重for循环变式----求排列数

leetcode 39. 组合总和---回溯篇2