The number of trailing zeroes in x! is determined by the number of times 5 divides numbers up to x. For a given k, we want to count how many x satisfy f(x) = k. It turns out that for any k, the set of x with f(x) = k is either 0 or 5 consecutive numbers. We can use binary search on the zeta function f(x) to find the leftmost and rightmost x such that f(x) = k.
Define a function f(x) that returns the number of trailing zeroes in x!. For a given k, the answer is the number of x such that f(x) = k, which we can denote as f_inv(k) = count(x | f(x) = k). This is equal to (right - left), where left is the smallest x with f(x) = k, and right is the smallest x with f(x) = k+1.
intzeta(int x) {
int res =0;
while (x) {
res += x /5;
x /=5;
}
return res;
}
intpreimageSizeFZF(int k) {
auto left = [](int k) {
long l =0, r =5L* k +5;
while (l < r) {
long m = l + (r - l) /2;
int z =0, x = m;
while (x) { z += x /5; x /=5; }
if (z < k) l = m +1;
else r = m;
}
return l;
};
return (int)(left(k+1) - left(k));
}
classSolution {
privateintzeta(int x) {
int res = 0;
while (x > 0) {
res += x / 5;
x /= 5;
}
return res;
}
privatelongleft(int k) {
long l = 0, r = 5L * k + 5;
while (l < r) {
long m = l + (r - l) / 2;
int z = 0, x = (int)m;
while (x > 0) { z += x / 5; x /= 5; }
if (z < k) l = m + 1;
else r = m;
}
return l;
}
publicintpreimageSizeFZF(int k) {
return (int)(left(k+1) - left(k));
}
}
funzeta(x: Int): Int {
var res = 0var x0 = x
while (x0 > 0) {
res += x0 / 5 x0 /=5 }
return res
}
funleft(k: Int): Long {
var l = 0Lvar r = 5L * k + 5while (l < r) {
val m = l + (r - l) / 2var z = 0var x = m
while (x > 0) {
z += (x / 5).toInt()
x /=5 }
if (z < k) l = m + 1else r = m
}
return l
}
funpreimageSizeFZF(k: Int): Int = (left(k+1) - left(k)).toInt()
defzeta(x: int) -> int:
res =0while x:
res += x //5 x //=5return res
defleft(k: int) -> int:
l, r =0, 5* k +5while l < r:
m = (l + r) //2 z, x =0, m
while x:
z += x //5 x //=5if z < k:
l = m +1else:
r = m
return l
defpreimageSizeFZF(k: int) -> int:
return left(k+1) - left(k)
fnzeta(mut x: i64) -> i64 {
letmut res =0;
while x >0 {
res += x /5;
x /=5;
}
res
}
fnleft(k: i64) -> i64 {
let (mut l, mut r) = (0, 5* k +5);
while l < r {
let m = l + (r - l) /2;
letmut z =0;
letmut x = m;
while x >0 {
z += x /5;
x /=5;
}
if z < k {
l = m +1;
} else {
r = m;
}
}
l
}
fnpreimage_size_fzf(k: i64) -> i64 {
left(k+1) - left(k)
}