连续子数组数量

给定一个数组,请你编写一个函数,返回元素乘积末尾零数量大于等于xx的连续子数组数量。
答案可能太大,请将答案对109+7取模再返回。

数组长度不超过105
数组元素、xx均为不超过109的正整数。

输入例子:
[5,2,3,50,4],2
输出例子:
6
例子说明:
共有以下6个合法连续子数组:
[5,2,3,50],乘积为1500,末尾有2个零。
[5,2,3,50,4],乘积为6000,末尾有3个零。
[2,3,50],乘积为300,末尾有2个零。
[2,3,50,4],乘积为1200,末尾有2个零。
[3,50,4],乘积为600,末尾有2个零。
[50,4],乘积为200,末尾有2个零。

其实既然是统计乘积末尾0的个数,转换一下就是统计作为乘数的数组元素种2和5因数的个数

说是双指针,感觉有点像是滑动窗口,我真不知道这是怎么想到的

/*
* 计算x中有多少个因子p
*/
int f(int x, int p) {
	int cnt = 0;
	while (x % p == 0) x /= p, cnt++;
	return cnt;
}

int getSubarrayNum(vector<int>& a, int x) {
	int i, j, len = a.size(), cnt2 = 0, cnt5 = 0, res = 0, mod = 1e9 + 7;
	// 这个循环相当于是在从第一个数组元素开始累加2,5因子的个数,直到满足要求(改右指针)
	for (i = 0, j = 0; i < len; i++) {
		// 统计每个数组元素2,5因子的个数
		cnt2 += f(a[i], 2);
		cnt5 += f(a[i], 5);
		// 当满足要求之后,改左指针直到不满足要求
		while (min(cnt2, cnt5) >= x) {
			cnt2 -= f(a[j], 2);
			cnt5 -= f(a[j], 5);
			j++;
		}
		res = (res + j) % mod;
	}
	return res;
}
posted @ 2022-12-23 15:26  YaosGHC  阅读(349)  评论(0)    收藏  举报