题意:给定n个数,问和等于k的次方的连续区间有多少个。
思路:思维题,假设前缀和数组为sum[],则有sum[i]-sum[j]==power(k)(j<i),power(k)带表k的某个次方数,如果枚举i和j的话复杂度是n^2,这个题肯定是过不了的,我们可以把式子变变形,sum[j]==sum[i]-power(k),可以先把所有的power(k)预处理出来,然后对每个sum[i]扫一遍power(k),判断有几个sum[j]满足上式,ans加上对应的数量就行了。注意这里j要小于i,因此要动态往map里加入sum[i],而不能一次性添加完再遍历。
代码:
#include<bits/stdc++.h>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,x,n) for(int i=x;i<n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
using namespace std;
typedef pair<int,int>P;
const int MAXN=100010;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
ll power[1010];
int cnt=0;
void init(ll k)
{
ll t=k;
power[cnt++]=1;
while(k<1e15)
{
power[cnt++]=k;
k*=t;
}
}
map<ll,int>num;
int main()
{
std::ios::sync_with_stdio(0);
int n;
ll k;
cin>>n>>k;
if(k!=1&&k!=-1)
init(k);
else
{
if(k==1)
power[cnt++]=1;
else
power[cnt++]=1,power[cnt++]=-1;
}
ll ans=0,sum=0,t;
num[0]=1;
for(int i=0;i<n;i++)
{
cin>>t;
sum+=t;
num[sum]++;
for(int j=0;j<cnt;j++)
ans+=num[sum-power[j]];
}
cout<<ans;
return 0;
}