题目大意
给你n个数,问你有多少个区间满足∏i=lrai∑i=lrai=k\frac{\prod_{i=l}^r a_i}{\sum_{i=l}^r a_i}=k∑i=lrai∏i=lrai=k
解题思路
原始等同于∏i=lrai=k⋅∑i=lrai\prod_{i=l}^r a_i=k\cdot\sum_{i=l}^r a_i∏i=lrai=k⋅∑i=lrai
先枚举起点,然后向后计算
对于ai≥2a_i\geq 2ai≥2,最多乘log(k∑ai)log(k\sum a_i)log(k∑ai)次
对于ai=1a_i=1ai=1,左边的项不会变,只有右边会+1,所以连续的一段1可以直接一次性解决
时间复杂度O(nlog(k∑ai))O(nlog(k\sum a_i))O(nlog(k∑ai))
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 200210
using namespace std;
ll n,k,x,y,mx,now,ans,a[N],nx[N];
int main()
{scanf("%lld%lld",&n,&k);for(ll i=1;i<=n;++i){scanf("%lld",&a[i]);mx+=a[i]*k;}a[n+1]=1;now=0;for(ll i=n;i>0;--i){nx[i]=now;if(a[i]==1)now++;//处理后面1的个数else now=0;}for(ll i=1;i<=n;++i){now=i;x=1;y=0;while(now<=n&&y<=mx-a[now]*k&&x<=mx/a[now]){x*=a[now];y+=a[now]*k;if(x==y)ans++;//直接构成if(x>y&&x<=y+nx[now]*k&&x%k==0)ans++;//后面的1y+=nx[now]*k;now+=nx[now]+1;}}printf("%lld",ans);return 0;
}