阶乘

阶乘

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);
		}
	}
}
原文地址:https://www.cnblogs.com/nibabadeboke/p/13498557.html