洛谷P3927 SAC E#1 - 一道中档题 Factorial

题目背景

数据已修改

SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友。

题目描述

SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。

这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。

SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。

但是SOL菌太菜了于是请你帮忙。

输入输出格式

输入格式:

每组输入仅包含一行:两个整数n,k。

输出格式:

输出一个整数:n!在k进制下后缀0的个数。

输入输出样例

输入样例#1: 
10 40
输出样例#1: 
2

说明

对于20%的数据,n <= 1000000, k = 10

对于另外20%的数据,n <= 20, k <= 36

对于100%的数据,n <= 10^12,k <= 10^12

update

1.一组数据

2.K不会==1

3.现在std没有爆long long

4.对数据有问题联系icy (建议大家不要面向数据编程)


根据进制的意义,在k进制的情况下逢k进1,那么末位就变为了0。题目要求求n!在k进制下末位的0,那么我们就可以求n!整除k多少次。该次数记为i。i就是答案。所以k^i<=n!。

由于n非常之大,求n!是不现实的。我们可以把k和n!分解质因数,举个栗子,n!=2^a 3^b 5^c....k同理。

因为n!是n的阶乘(废话)所以n里面有的质因数在n!里也存在。再思考k与n!的关系可以知道,如果一个质因数存在于n中,但不存在于k中,我们是无需理会的。所以我们只需要分解k的质因数就可以了。之后我们再判断从k分解出来的质因数也是不是n的质因数。如果是的话,假设n!中2的个数为a(同上栗子),k中2的个数为x,那么a整除x就是有可能为答案。因为n!和k的相同质因数可能有多个,所以我们就要找某个a整除某个x的最小值(值大了小的受不了),这个值就是答案了。

#include
#include
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=200005;
long long n,k,a[MAXN],b[MAXN],cnt;
long long ans=200000000000;
int main()
{
	ios::sync_with_stdio(false);
	long long i,j;
	cin>>n>>k;
	for(i=2;i*i<=k;i++){
		if(k%i==0){
			a[++cnt]=i;
			while(k%i==0){
				b[cnt]++;
				k/=i;
			}
		}
	}
	if(k>1){
		a[++cnt]=k;
		b[cnt]=1;
	}
	f(i,1,cnt){
		long long t=0,tmp=n;
		while(tmp){
			t+=tmp/a[i];
			tmp/=a[i];
		}
		t/=b[i];
		ans=min(ans,t);
	}
	cout<


你可能感兴趣的:(数学)