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 }