【枚举】【前缀和】【map】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals

处理出前缀和,枚举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;
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/6438101.html