D-Kevin喜欢零(简单版本)_牛客小白月赛73 (nowcoder.com)
题意:
思路:
一个数末尾0的个数取决于min(cnt2,cnt5)的数量
考虑枚举l,然后二分r
注意,要二分的是合法区间的左边界和合法区间的右边界
这种二分方式很常见,务必掌握
然后答案区间就取max(l1,r1),max(r1,r2)即可
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mxn=3e5+10;
const int mxe=3e5+10;
int N,K;
int a[mxn];
int ca[mxn],cb[mxn];
int pre_a[mxn],pre_b[mxn];
void solve(){
cin>>N>>K;
for(int i=0;i<=N+10;i++) pre_a[i]=pre_b[i]=ca[i]=cb[i]=0ll;
for(int i=1;i<=N;i++) cin>>a[i];
for(int i=1;i<=N;i++){
int u=a[i];
while(u%2==0) u/=2,ca[i]++;
while(u%5==0) u/=5,cb[i]++;
}
for(int i=1;i<=N;i++){
pre_a[i]=pre_a[i-1]+ca[i];
pre_b[i]=pre_b[i-1]+cb[i];
}
int ans=0;
for(int l=1;l<=N;l++){
int v1=K+pre_a[l-1];
int v2=K+pre_b[l-1];
int l1=lower_bound(pre_a+1,pre_a+1+N,v1)-pre_a;
int r1=upper_bound(pre_a+1,pre_a+1+N,v1)-pre_a-1;
int l2=lower_bound(pre_b+1,pre_b+1+N,v2)-pre_b;
int r2=upper_bound(pre_b+1,pre_b+1+N,v2)-pre_b-1;
int L=max(l1,l2);
int R=max(r1,r2);
if(L==N+1) continue;
L=max(L,l);
ans+=(R-L+1);
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int __=1;cin>>__;
while(__--)solve();return 0;
}