题目非常好懂,题意是给你n!和k个后缀零数,让你求出符合条件的进制b的个数。
假设你已经会求n!的质因数分解,再解释第一组样例。n=10,k=2,n!的阶乘可以表示为2^8*3^4*5^2*7,再转换成这种形式(2^4*3^2*5)^2*7,可以知有多少种进制满足条件,就是2^4*3^2*5的组合,一共有5*3*2种,其中肯定有不满足条件的,2^0,2^1,2^2,3^0,3^1,5^0,一共有3*2*1种,30-6等于24种。为什么不满足条件呢,因为如果有那种进制就会产生多余的0。
代码如下
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10000;
typedef long long LL;
const LL mod = 1000000000+7;
int T;
LL n,k;
int Pri[maxn],num[maxn],vis[maxn];
int cnt=1;
int prime()
{
memset(vis,0,sizeof vis);
for(int i = 2; i<10000; i++)
if(!vis[i])
{
Pri[cnt++]=i;
for(int j=i+i; j<10000; j+=i)
vis[j]=1;
}
}
int solve(int n,int p)
{
if(n<p)return 0;
return n/p+solve(n/p,p);
}
int main()
{
prime();
// for(int i=1; i<=cnt; i++)
// printf("%d\n",Pri[i]);
scanf("%d",&T);
while(T--)
{
memset(num, 0, sizeof num);
scanf("%I64d%I64d",&n,&k);
LL ans =1 , ans1 = 1;
int i;
for(i=1; i<=cnt; i++)
{
int tt = n;
num[i]=solve(tt,Pri[i]);
if(num[i]>=k)
{
LL temp = num[i]/k+1;
ans = (ans*temp)%mod;
LL temp1 = temp-1;
int js=0;
for(int j=1 ; j<=temp1; j++)
{
if(num[i]/j!=k)
js++;
}
ans1 = (ans1*(js+1))%mod;
// printf("%I64d\n",ans1);
}
else break;
}
printf("%I64d\n",((ans-ans1)%mod+mod)%mod);
}
}
原文地址:http://blog.csdn.net/zh9406/article/details/46432583