核心在于求数字n!的素数因子i的个数
考虑1-n中所有数字中含有因子i的数字的个数,含有因子2i的数字的个数……
则n/i可得含有因子i的数字个数,n/2i可得含有因子2i的数字的个数……
全部相加,就是n!的素数因子i的个数了
又排列数A(N,M)= N! / (N-M)!
因为当分子分母含有同一个因子时可约
所以A(N,M)含有素数因子i的个数即
【分子含有素数因子i的个数-分母含有素数因子i的个数】
比如说10!有多少个素因子2?
我们一层一层考虑:(数字1到10中)有因子2的数个数+有因子4的数个数+有因子8的数个数+…….
10/2(数字是2,4,6,8,10)+10/2/2(4,8)+10/2/2/2(8)
#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long LL;
//x中有多少个素因子k?
//1-x中有素因子k的数的个数,有素因子2k的数的个数……
const int MOD=1000000007;
LL k;
LL f(LL x){
LL ans=0;
while(x){
ans+=x/k;
ans%=MOD;
x/=k;
}
return ans;
}
int main()
{
LL n,m;
cin>>n>>m>>k;
LL y=f(n)-f(n-m);
y=(y%MOD+MOD)%MOD;//这样取模可以避免负数所得结果是负数的问题
cout<<y;
return 0;
}
#include<cstdio>
#include<iostream>
using namespace std;
int cnt[100 + 10];
bool check(int x) {//判断x是否为素数
for (int i = 2; i < x; i++) {
if (x % i == 0) return 0;
}
return 1;
}
int solve(int x,int k) {//求x中素数因子k的个数
int num = 0;
while (x) {
num += x / k;
x /= k;
}
return num;
}
int main()
{
//要求i的正因子个数为50
//由唯一分解定理:i=p1^k1*p2^k2*p3^k3……
//可知i的正因子个数50由式子(k1+1)*(k2+1)*(k3+1)……给出
//而50=1*50=2*25=10*5=2*5*5共四种情况
//所以式子有四种情况
//k1=49
//k1=1;k2=24
//k1=9;k2=4
//k1=1;k2=4;k3=4
//显然这个i同时符合条件①与②
//(注意i|(n!)是n!%i==0的意思,由于i就是2-n之间的数字,必定符合
int n;
cin >> n;
//找出2-n之间的素数i,求出n有多少个素数因子i
for (int i = 2; i <= n; i++) {
if (check(i)) cnt[i]=solve(n,i);
}
long long ans=0;
for (int i = 2; i <= n; i++) {
if (cnt[i] >= 49) ans++;
//n中的素数因子i≥49个
//有1个符合条件的i
}
for (int i = 2; i <= n; i++) {
if (cnt[i] >= 1) {
for (int j = 2; j <= n; j++) {
if (cnt[j] >= 24 && j != i) ans++;
}
}
}
for (int i = 2; i <= n; i++) {
if (cnt[i] >= 4) {
for (int j = 2; j <= n; j++) {
if (cnt[j] >= 9 && j != i) ans++;
}
}
}
for (int i = 2; i <= n; i++) {
if (cnt[i] >= 4) {
for (int j = i + 1; j <= n; j++) {
if (cnt[j] >= 4 && j != i) {
for (int k = 2; k <= n; k++) {
if (cnt[k] >= 1 && k != j && k != i) ans++;
}
}
}
}
}
cout << ans;
return 0;
}