题目来源:POJ 2992 Divisors
题意:。。。
思路:素数分解的唯一性 一个数可以被分解成若干素数相乘 p1^x1*p2^x2*...*pn^xn
根据乘法原理 因子数为 (x1+1)*(x2+1)*...*(xn+1)
不能直接求出组合数 会溢出 也不能把每个乘的数分解因子 这样会超时
C(N,M)=N!/(M!*(N-M)!)
另dp[i][j] 代表为i的阶乘中j因子的个数(j是素数)
那么i素数的个数为dp[n][i]-dp[m][i]-dp[n-m][i]
最后for循环从1到n枚举i统计
#include <cstdio> #include <cstring> #include <cmath> using namespace std; const int maxn = 500; int vis[maxn]; int prime[maxn]; int dp[maxn][maxn]; //筛素数 void sieve(int n) { int m = sqrt(n+0.5); memset(vis, 0, sizeof(vis)); vis[0] = vis[1] = 1; for(int i = 2; i <= m; i++) if(!vis[i]) for(int j = i*i; j <= n; j += i) vis[j] = 1; } int get_primes(int n) { sieve(n); int c = 0; for(int i = 2; i <= n; i++) if(!vis[i]) prime[c++] = i; return c; } int get(int n, int m) { int sum = 0; while(n) { sum += n/m; n /= m; } return sum; } void pre(int n) { for(int i = 2; i <= n; i++) { for(int j = 2; j <= i; j++) dp[i][j] = get(i, j); } } int main() { int c = get_primes(444); pre(444); int n, m; while(scanf("%d %d", &n, &m) != EOF) { long long ans = 1; for(int i = 2; i <= n; i++) { if(vis[i]) continue; //C(N,M)=N!/(M!*(N-M)!) ans *= dp[n][i] - dp[m][i] - dp[n-m][i] + 1; } printf("%lld\n", ans); } return 0; }
POJ 2992 Divisors 求组合数因子个数,布布扣,bubuko.com
时间: 2024-10-14 06:12:57