https://www.luogu.org/problemnew/show/P3927
题目背景
数据已修改
SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友。
题目描述
SOL君很喜欢阶乘。而SOL菌很喜欢研究进制。
这一天,SOL君跟SOL菌炫技,随口算出了n的阶乘。
SOL菌表示不服,立刻就要算这个数在k进制表示下末尾0的个数。
但是SOL菌太菜了于是请你帮忙。
输入输出格式
输入格式:
每组输入仅包含一行:两个整数n,k。
输出格式:
输出一个整数:n!在k进制下后缀0的个数。
cf遇到的一题,后来听说luogu上有原题。当时想出来了但是没时间写,现在补一下。
分析:
要想有0,那么肯定是有因子k,同时,k的个数也就是k的个数。那么就是求n!里因子k的个数咯。可以考虑将k质因数分解。设一个质因子为x,x的指数为t(唯一分解)那么k的个数就为min(n!里x的个数/t)。然后就是解决求n!里x的个数。n!里x的个数=n!/x+n!/x*x+n!/x*x*x....。就解决了这个问题。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<algorithm>
#include<cmath>
#define rg register
#define il inline
using namespace std;
typedef unsigned long long ll;
ll read(){
ll ans=0,flag=1;char ch;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') flag=-1;
ans=ch^48;
while((ch=getchar())>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+(ch^48);
return flag*ans;
}
void write(ll x){
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
struct factor{
int val,cnt;
factor(int val,int cnt):val(val),cnt(cnt){}
};
int main(){
ll n=read(),k=read(),cnt;
queue<factor> q;ll t=k;
for(rg ll i=2;k!=1&&i*i<=t;i++){
if(k%i==0){
cnt=0;
while(k%i==0){
cnt++;
k/=i;
}q.push(factor(i,cnt));
}
}
if(k>1) q.push(factor(k,1));
ll ans=1e12;
while(!q.empty()){
factor f=q.front();q.pop();
long long t=0,now=n;
while(now)t+=now/=f.val;
t/=f.cnt;
if(t<ans)ans=t;
}
cout<<ans;
return 0;
}