描述
有
n
n
n 个数的数组
a
a
a 下标从
1
1
1 开始,数组中每个元素不超过
1
e
9
1e9
1e9 ,
设
f
(
l
,
r
,
x
)
=
[
(
∑
i
=
l
r
a
[
i
]
)
=
=
x
]
f(l,r,x)=[(\sum_{i=l}^{r}a[i])==x]
f(l,r,x)=[(∑i=lra[i])==x] (
[
a
=
=
b
]
[a==b]
[a==b])表示
0
/
1
0/1
0/1 。
求
∑
l
=
1
n
∑
r
=
l
n
f
(
l
,
r
,
x
)
\sum_{l=1}^{n}\sum_{r=l}^{n}f(l,r,x)
∑l=1n∑r=lnf(l,r,x)的值
分析
设
p
x
=
∑
i
=
1
x
a
[
i
]
p^x=\sum_{i=1}^{x}a[i]
px=∑i=1xa[i] ,
所以假设
p
r
−
p
l
−
1
=
x
p^r-p^{l-1}=x
pr−pl−1=x =>
p
r
−
x
=
p
l
−
1
p^r-x=p^{l-1}
pr−x=pl−1
只需要每次将
a
n
s
+
贡
献
(
p
r
−
x
)
ans+贡献(p^r-x)
ans+贡献(pr−x)并使
贡
献
p
l
−
1
贡献p^{l-1}
贡献pl−1++即可
#include <bits/stdc++.h>
using namespace std;
using ll = long long ;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
vector<int>a(n+1);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
unordered_map<ll,ll>mp;
mp[0]=1;
ll ans=0,sum=0;
for(int i=1;i<=n;i++){
sum+=a[i];//前缀和
ans+=mp[sum-m];//相当于找 $p^r-s==p^{l-1}对应p^{l-1}的个数$
mp[sum]++;//此时相当于左侧的 $p^{l-1}$ 了
}
printf("%lld\n",ans);
}