阶乘
Description
Input
第一行有一个正整数T,表示测试数据的组数。
接下来的T行,每行输入两个十进制整数n和base。
Output
对于每组数据,输出一个十进制整数,表示在base进制下,n!结尾的零的个数。
Sample Input
2
10 10
10 2
Sample Output
2
8
Data Constraint
对于20%的数据,n<=20,base<=16
对于50%的数据,n<=109,base<=105
对于100%的数据,1<=T<=50,0<=n<=1018,2<=base<=1012
解题思路
题意为求(n! = base ^ i * g)中的(i)
对 (n) 和 (base) 都进行质因数分解即可求出
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
long long n,m,d[1000010],c[1000010];
int t,vis[1000010],p[1000010],tot = 0,cnt = 0;
void init()
{
vis[1] = 1;
for (int i = 2; i <= 1000005; i++)
{
if (!vis[i]) p[++tot] = i;
for (int j = 1; j <= tot && p[j] * i <= 1000005; j++)
{
vis[p[j] * i] = 1;
if (i % p[j] == 0) break;
}
}
}
int main()
{
init();
scanf("%d",&t);
while (t--)
{
scanf("%lld%lld",&n,&m);
int i = 1;
long long y = m;
cnt = 0;
memset(c,0,sizeof(c));
while (y > 1)
{
if (i > tot) break;
if (y % p[i] == 0) d[++cnt] = p[i];
while (y % p[i] == 0) c[cnt]++,y /= p[i];
i++;
}
if (y != 1 && y) d[++cnt] = y,c[cnt]++;
if (cnt)
{
long long mv = 0x3f3f3f3f3f3f3f3f;
for (i = 1; i <= cnt; i++)
{
long long k = 0,l = d[i];
while (l <= n)
{
k += (long long)n / l;
if (l > n / d[i]) break;
l *=(long long) d[i];
}
mv = min(mv,k / c[i]);
}
printf("%lld
",mv);
}
else
{
long long k = 0,l = m;
while (l <= n)
{
k += (long long)n / l;
if (l > n / m) break;
l *= (long long)m;
}
printf("%lld
",k);
}
}
}