分析 给定正整数
n
,
k
n,k
n,k,已知非负整数
x
x
x满足
n
!
m
o
d
  
k
x
=
0
n!{\mod}k^x = 0
n!modkx=0,求
x
m
a
x
x_{max}
xmax。 考虑唯一分解定理
n
!
n!
n! 可以分解为
p
1
c
1
∗
p
2
c
2
∗
.
.
.
p
k
c
k
p_1^{c_1}*p_2^{c_2}*...p_k^{c_k}
p1c1∗p2c2∗...pkck
k
x
k^x
kx 可以分解为
p
1
a
1
∗
x
∗
p
2
a
2
∗
x
.
.
.
p
m
c
m
∗
x
p_1^{a_1*x}*p_2^{a_2*x}...p_m^{c_m*x}
p1a1∗x∗p2a2∗x...pmcm∗x 所以不论
k
k
k的几次方,
k
k
k分解出来的
p
p
p应该不变。 考虑
n
!
n!
n!分解出来
p
p
p的集合,如果存在一个
p
∈
k
x
,
p
∉
n
!
p{\in}{k^x},p{\notin}n!
p∈kx,p∈/n!,那么
n
!
m
o
d
  
k
x
!
=
0
n!{\mod}k^x\hspace{1em}!= 0
n!modkx!=0,
x
=
0
x = 0
x=0. 可以发现,只要对于
k
k
k分解质因数,再用
k
k
k的范围内的质数结合老套路对
n
!
n!
n!分解质因数,求出
c
i
c_i
ci,最后用
c
i
a
i
{\frac{c_i}{a_i}}
aici更新
x
x
x的最小值即可。更新最小值是因为要满足整除。不考虑
n
!
n!
n!分解质因数是因为大于
k
k
k的素数部分一定满足整除,对答案没有影响。比如:
x
=
2
3
∗
3
3
∗
5
2
2
2
∗
3
x = \frac{2^3*3^3*5^2}{2^2*3}
x=22∗323∗33∗52,这里
5
2
5^2
52没有影响直接在
x
x
x中累计即可。
代码
/*
独立思考
一个题不会做,收获5%,写了代码10%,提交对了30%,总结吃透了这个题才是100%.
*/#include<bits/stdc++.h>usingnamespace std;template<typename T>voidread(T &x){
x =0;char c =getchar();int sgn =1;while(c <'0'|| c >'9'){if(c =='-')sgn =-1; c =getchar();}while(c >='0'&& c <='9')x = x *10+ c -'0', c =getchar();
x *= sgn;}template<typename T>voidout(T x){if(x <0){putchar('-'); x =-x;}if(x >=10)out(x /10);putchar(x %10+'0');}typedeflonglong ll;typedefunsignedlonglong ull;
ll gcd(ll a, ll b){return b ?gcd(b, a % b): a;}
ll solve(ll x, ll y){if(y > x)return0;return x / y +solve(x / y, y);}constint N =5000009;
ll prime[N];bool v[N];int tot =0;
ll c =0;voidsieve(){for(int i=2;i<=3400000;i++){if(!v[i])
prime[++tot]=i;for(int j=1;j<=tot&&i*prime[j]<=3400000;j++){
v[i*prime[j]]=1;if(i%prime[j]==0)break;}}}int main (){sieve();
ll n, k;while(~scanf("%lld %lld",&n,&k)){
ll ans =9e18;for(int i =1; prime[i]*prime[i]<= k; i++){if(k % prime[i]==0){
c =0;while(k % prime[i]==0){
c ++;
k /= prime[i];}
ans =min(ans,solve(n, prime[i])/ c);}}if(k !=1) ans =min(ans,solve(n, k));
cout<<ans<<endl;}return0;}