方法数很显然是A(n,m),阶乘又具有前缀和的性质,转化为经典问题(n!中可以最多是k的多少幂次),注意分解质因数。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
LL prime[100];
LL tpow[100];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
LL n,m,k;
LL ans=-1;
scanf("%lld%lld%lld",&n,&m,&k);
LL low=n-m+1,up=n;
memset(prime,0,sizeof(prime));
memset(tpow,0,sizeof(tpow));
LL tmp=k;
LL bound=(LL)(sqrt(k)+1);
int cnt=0;
for(int i=2;i<=bound;i++)
{
if(tmp%i==0)
{
prime[cnt]=i;
while(tmp%i==0)
{
tpow[cnt]++;
tmp/=i;
}
cnt++;
}
}
if(tmp!=1)
{
prime[cnt]=tmp;
tpow[cnt++]=1;
}
for(int i=0;i<cnt;i++)
{
LL tans=0;
tmp=n;
while(tmp)
{
tans+=tmp/prime[i];
tmp/=prime[i];
}
tmp=n-m;
while(tmp)
{
tans-=tmp/prime[i];
tmp/=prime[i];
}
tans/=tpow[i];
if(ans==-1) ans=tans;
else ans=min(ans,tans);
}
printf("%lld\n",ans);
}
return 0;
}