https://codeforces.com/contest/1114/problem/C
题意
输入一个n和b。
1
≤
n
≤
1
0
18
1\leq n\leq 10^{18}
1≤n≤1018,
2
≤
b
≤
1
0
12
2 \leq b \leq 10^{12}
2≤b≤1012。
输出n! 在b进制下,末尾连续0的个数。
例如5 2
120 = 1111000
末尾连续0的个数为3。
题解
n
!
=
x
k
∗
b
y
k
+
x
k
−
1
∗
b
y
k
−
1
+
⋯
+
x
1
∗
b
y
1
n! = x_k*b^{y_k}+x_{k-1}*b^{y_{k-1}}+\dots+x_1*b^{y_1}
n!=xk∗byk+xk−1∗byk−1+⋯+x1∗by1。
转换成的b进制数为
x
k
x
k
−
1
…
x
1
x_kx_{k-1}\dots x_1
xkxk−1…x1。
当
n
!
m
o
d
b
k
=
=
0
n! \ mod \ b^k == 0
n! mod bk==0时,
x
k
x_k
xk就为0。
所以只要知道何时不整除
b
k
b^k
bk就可以了。
但是n的范围特别大,不可能算出n的阶乘。
所以考虑质因子分解。
n
!
=
p
1
m
1
p
2
m
2
…
p
r
m
r
n!=p_1^{m1}p_2^{m2}\dots p_r^{mr}
n!=p1m1p2m2…prmr
b
=
p
1
k
1
p
2
k
2
…
p
r
k
r
b=p_1^{k1}p_2^{k2}\dots p_r^{kr}
b=p1k1p2k2…prkr
算出b中的每个质因子p在
n
!
n!
n!中的贡献,例如2在6!中出现的次数tmp是6/2+6/4=4。即因子2作为2出现的次数加上作为4出现的次数。以此类推。
然后tmp/k1即使
p
k
1
p^{k1}
pk1出现的次数。
最后取所有的出现次数的最小值便是
b
r
b^r
br中的r。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll n,b;
cin >> n >> b;
ll ans = 1ll<<60;
for(ll i = 2; i <= b; ++i) {
if(1ll*i*i > b) i = b;
// cout << i << endl;
int cnt = 0;
if(b%i == 0) {
while(b%i == 0) {
b /= i;
cnt++; // p^cnt
}
ll mul = 1;
ll tmp = 0;
while(n/i >= mul) {
mul*=i;
tmp += n/mul;
}
ans = min(ans, tmp/cnt);
}
}
cout << ans << endl;
return 0;
}