Preimage Size of Factorial Zeroes Function

hard binary-search math

Problem

Let f(x) be the number of trailing zeroes in x!. Given k, return how many non-negative integers x satisfy f(x) == k. The answer is always 0 or 5.

Inputk = 0
Output5
0!, 1!, 2!, 3!, 4! all end in 1, so five values give 0 trailing zeroes.

def preimageSizeFZF(k):
    def zeta(x):
        r = 0
        while x:
            x //= 5
            r += x
        return r
    lo, hi = 0, 5 * (k + 1)
    while lo < hi:
        mid = (lo + hi) // 2
        if zeta(mid) < k:
            lo = mid + 1
        else:
            hi = mid
    return 5 if zeta(lo) == k else 0
var preimageSizeFZF = function(k) {
    const zeta = (x) => { let r = 0; while (x) { x = Math.floor(x / 5); r += x; } return r; };
    let lo = 0, hi = 5 * (k + 1);
    while (lo < hi) {
        const mid = Math.floor((lo + hi) / 2);
        if (zeta(mid) < k) lo = mid + 1;
        else hi = mid;
    }
    return zeta(lo) === k ? 5 : 0;
};
class Solution {
    private long zeta(long x) { long r = 0; while (x > 0) { x /= 5; r += x; } return r; }
    public int preimageSizeFZF(int k) {
        long lo = 0, hi = 5L * (k + 1);
        while (lo < hi) {
            long mid = (lo + hi) / 2;
            if (zeta(mid) < k) lo = mid + 1;
            else hi = mid;
        }
        return zeta(lo) == k ? 5 : 0;
    }
}
class Solution {
    long long zeta(long long x) { long long r = 0; while (x) { x /= 5; r += x; } return r; }
public:
    int preimageSizeFZF(int k) {
        long long lo = 0, hi = 5LL * (k + 1);
        while (lo < hi) {
            long long mid = (lo + hi) / 2;
            if (zeta(mid) < k) lo = mid + 1;
            else hi = mid;
        }
        return zeta(lo) == k ? 5 : 0;
    }
};
Time: O(log^2 k) Space: O(1)