题目描述
输入
第一行有一个正整数T,表示测试数据的组数。
接下来的T行,每行输入两个十进制整数n和base。
输出
对于每组数据,输出一个十进制整数,表示在base进制下,n!结尾的零的个数。
输入样例
2
10 10
10 2
输出样例
2
8
说明
对于20%的数据,n<=20,base<=16
对于50%的数据,n<=10^9,base<=10 ^5
对于100%的数据,1<=T<=50,0<=n<=10^18,2<=base<=10 ^ 12
.
.
.
.
.
.
分析
只要看 n! 有多少个 m的倍数就好了
考虑分解 m 的质因子
然后计算每个因子在 n!中有多少个(1~n /2的商之和即为2在n!中的个数)
取能取到的最小值就行了
.
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
long long prime[1000000],count[1000000];
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
long long n,m;
scanf("%lld%lld",&n,&m);
memset(prime,0,sizeof(prime));
memset(count,0,sizeof(count));
long long tj=0,m1=(long long)sqrt(m);
for (long long x=2;x<=m1;x++)
{
if (m==1) break;
if (m%x==0)
{
prime[++tj]=x;
while (m%x==0)
{
m/=x;
count[tj]++;
}
}
}
if (m>1)
{
prime[++tj]=m;
count[tj]++;
}
long long ans=9223372036854775807;
for (int i=1;i<=tj;i++)
{
long long sum=0,n1=n;
while (n1>=prime[i])
{
n1=(long long)n1/prime[i];
sum=(long long)sum+n1;
}
if (count[i]!=0) ans=min(ans,sum/count[i]);
}
printf("%lld\n",ans);
}
return 0;
}