题意:给定一个数组,求子数组的乘积/子数组的和=k的个数
分析:由于ai的范围是1e8,n是2e5。和最多为1e13,k最大是1e5,所以子数组乘积最多不超过2e18,乘以1时候乘积不变,跳过所有的1,每次按照乘以2的话最多乘60次,复杂度为O(n * 60)。有
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
ll a[maxn];
int cnt[maxn];
const ll INF = 2e18;
int main()
{
ll n,k;
cin>>n>>k;
for(int i = 1; i <= n; i++)
cin>>a[i];
int res = 0;
for(int i = n; i >= 1; i--)
{
if(a[i] == 1)
{
cnt[i - 1] = cnt[i] + 1;
}
}
for(int i = 1; i <= n; i++)
{
ll sum = 0,mul = 1LL;
for(int j = i; j <= n; j++)//跳过所有的1,最多不超过60次
{
sum += a[j];
if(mul > INF / a[j])//注意直接乘会爆long long
break;
mul *= a[j];
if(sum * k == mul)
res++;
else
{
if(sum * k < mul && (mul % k == 0) && (mul / k >= sum) && (mul / k <= sum + cnt[j]))
res++;
int x = cnt[j];
j += x;
sum += x;//j变了
}
}
}
cout<<res<<endl;
return 0;
}