小美的区间删除

29 阅读1分钟

小美拿到了一个大小为n的数组,她希望删除一个区间后,使得剩余所有元素的乘积末尾至少有k个 0。小美想知道,一共有多少种不同的删除方案?

输入例子:

5 2
2 5 3 4 20

输出例子:

4

例子说明:

第一个方案,删除[3]。
第二个方案,删除[4]。
第三个方案,删除[3,4]。
第四个方案,删除[2]
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
    // Write your code here
    let params = [];
    while ((line = await readline())) {
        let tokens = line.split(" ");
        // let a = parseInt(tokens[0]);
        // let b = parseInt(tokens[1]);
        // console.log(a + b);
        params.push(tokens);
    }
    // console.log(params)
    let [n, k] = params[0].map(Number);
    let arr = params[1].map(Number);
    // console.log(n, k, arr);
    // 总的删除可能次数
    // let total = ((n + 1) * n) / 2;
    // 0的个数 由 2 和 5 的个数决定 统计删除空间2和5的个数
    function counterFactor(num, factor) {
        let count = 0;
        while (num % factor == 0) {
            count++;
            num /= factor;
        }
        return count;
    }
    let prefix2 = Array.from({ length: n + 1 }).fill(0);
    let prefix5 = Array.from({ length: n + 1 }).fill(0);
    for (let i = 0; i < arr.length; i++) {
        prefix2[i + 1] = prefix2[i] + counterFactor(arr[i], 2);
        prefix5[i + 1] = prefix5[i] + counterFactor(arr[i], 5);
    }
    let count = 0;
    // 滑动窗口计算
    function check(l, r) {
        let remaining2 = prefix2[n] - prefix2[r + 1] + prefix2[l];
        let remaining5 = prefix5[n] - prefix5[r + 1] + prefix5[l];
        return Math.min(remaining2, remaining5) >= k;
    }
    for (let l = 0; l < n; l++) {
        // for(let r=l;r<n;r++){
        // 如果当前区间
        // if(Math.min(remaining2,remaining5)>=k){
        // count++
        // }
        // }
        // 通过二分查找查找到下一个满足的点
        let found = -1;
        let left = l;
        let right = n - 1;
        // 找到第一个满足条件的
        while (left <= right) {
            let mid = Math.floor((left + right) / 2);
            if (check(l, mid)) {
                left = mid + 1;
                found = mid;
            } else {
                right = mid - 1;
            }
        }
        if (found != -1) {
            count += found - l + 1;
        }
    }
    console.log(count);
})();