首先,根据10^k的要求,我们可以把条件转化成 (10^k) = (2 * 5)^k;那么问题就转化成了求满足[l,r]区间内2,5的幂次的最小值 = k的所有区间。这里我们采用前缀和,分别统计2和5的个数的前缀和,然后二分求出以i为左边界的上下限右区间,这里特别注意,只要2或者5幂次的最小值是k即可。特别注意写代码的时候,我们想要的区间是在i及i的右边,所以求出的区间可能会在i的左边,这个时候一定要小心...
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#define Mod 7452454545
#include <map>
#include <set>
#include <unordered_map>
#include <vector>
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int, int>
#define PLL pair<long, long>
#define x first
#define y second
#define INF 0x3f3f3f3f
#define ULL unsigned long long
#define kanm7 ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
using namespace std;
const int N = 2e5 + 10;
int f[N];
int n, k;
int cnt2[N], cnt5[N];
queue<int> q;
int main() {
kanm7;
int T; cin >> T;
while(T --) {
cin >> n >> k;
for(int i = 1; i <= n; i ++) {
int x; cin >> x;
int s = 0;
while(x % 2 == 0) {
s ++;
x /= 2;
}
cnt2[i] = s;
s = 0;
while(x % 5 == 0) {
s ++;
x /= 5;
}
cnt5[i] = s;
cnt2[i] += cnt2[i - 1];
cnt5[i] += cnt5[i - 1];
}
LL ans = 0;
for(int i = 1; i <= n; i ++) {
int r21 = lower_bound(cnt2 + 1, cnt2 + n + 1, cnt2[i - 1] + k) - cnt2;
int r22 = upper_bound(cnt2 + 1, cnt2 + n + 1, cnt2[i - 1] + k) - cnt2;
r22 --;
int r51 = lower_bound(cnt5 + 1, cnt5 + n + 1, cnt5[i - 1] + k) - cnt5;
int r52 = upper_bound(cnt5 + 1, cnt5 + n + 1, cnt5[i - 1] + k) - cnt5;
r52 --;
int l = max({r21, r51, i});
int r = max({r22, r52});
if(l == n + 1 || r < i) continue;
ans += r - l + 1;
}
cout << ans << endl;
}
return 0;
}