处理出前缀和,枚举k的幂,然后从前往后枚举,把前面的前缀和都塞进map,可以方便的查询对于某个右端点,有多少个左端点满足该段区间的和为待查询的值。
#include<cstdio> #include<map> using namespace std; typedef long long ll; map<ll,int>cnts; int n,m,e; ll a[100010],ans; ll b[1001]; int main() { // freopen("c.in","r",stdin); scanf("%d%d",&n,&m); if(m==0 || m==1) b[++e]=m; else if(m==-1) { b[++e]=m; b[++e]=-m; } else { ll now=1ll; while(now<=100000000000000ll && now>=-100000000000000ll) { b[++e]=now; now*=(ll)m; } } for(int i=1;i<=n;++i) scanf("%I64d",&a[i]); for(int i=2;i<=n;++i) a[i]+=a[i-1]; ++cnts[0]; for(int i=1;i<=n;++i) { for(int j=1;j<=e;++j) ans+=cnts[a[i]-b[j]]; ++cnts[a[i]]; } printf("%I64d ",ans); return 0; }