FZU 1851 组合数

 

  给你两个数n和m,然后让你求组合数C(n,m)中的质因子的个数。

  这里用到的一个定理:判断阶乘n!中的质因子 i 的个数的方法---f(n!)=n/i+n/i^2+n/i^3+.....n/i^m (i为一个质因子,m是使n/i^m=0的最小值);

   又已知C(n,m)=n!/ ( m!·(n-m)! ) ; 所以需要n!中所有的质因子的个数,然后再减去m! 和 (n-m)! 这些质因子的个数,得到的结果就是该组合数质因子的个数。

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <cstdlib>
 7 #include <cctype>
 8 #include <queue>
 9 #include <stack>
10 #include <map>
11 #include <vector>
12 #include <set>
13 #include <utility>
14 #define ll long long
15 #define inf 0x3f3f3f3f
16 using namespace std;
17 
18 const int N=1e6+7;
19 bool book[N];
20 vector<int> prime;
21 void get_prime() //筛法预处理素数表
22 {
23     fill(book,book+N,false);
24     for(int i=2;i<N;i++)
25     {
26         if(!book[i])
27         {
28             prime.push_back(i);
29             for(int j=i+i;j<N;j+=i)
30                book[j]=true;
31         }
32     }
33 }
34 int main()
35 {
36     //freopen("input.txt","r",stdin);
37     get_prime();
38     int n,m;
39     while(scanf("%d%d",&n,&m)&&n&&m)
40     {
41         int res=0;
42         int len=prime.size();
43         for(int i=0;i<len&&prime[i]<=n;i++)
44         {       //分别计算n!、m!、(n-m)! 中含有质因子prime[i]的个数,再把n!的个数减去m!和(n-m)!的个数
45             int tn=n,tm=m,tt=n-m,cnt=0;
46             while(tn)
47             {
48                 cnt+=tn/prime[i];
49                 tn/=prime[i];
50             }
51             while(tm)
52             {
53                 cnt-=tm/prime[i];
54                 tm/=prime[i];
55             }
56             while(tt)
57             {
58                 cnt-=tt/prime[i];
59                 tt/=prime[i];
60             }
61             if(cnt) res++;
62         }
63         printf("%d\n",res);
64     }
65     return 0;
66 }

 

posted @ 2016-07-22 13:34  爱喝可乐的咖啡  阅读(171)  评论(0编辑  收藏  举报