思路
现在我们可以写一个公式(sum代表前缀和数组)
s
u
m
[
i
]
−
s
u
m
[
j
]
=
i
−
j
sum[i]-sum[j]=i-j
sum[i]−sum[j]=i−j
移项可得
s
u
m
[
i
]
−
i
=
s
u
m
[
j
]
−
j
sum[i]-i=sum[j]-j
sum[i]−i=sum[j]−j
那么代表这个存在一个这种情况(这个代表一对)
那么我们就可以愉快的开始实现我们的代码了
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
ll sum[21021000];
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
getchar();
map<ll,ll>mp;
ll ans=0;
for(int i=1;i<=n;i++){
char s;
cin>>s;
sum[i]=sum[i-1]+s-'0';
ans+=mp[sum[i]-i]++;
}
cout<<ans<<endl;
}
}
样例都过不去。。。。无语子
为什么呢因为
s
u
m
[
i
]
=
i
sum[i]=i
sum[i]=i
这个情况我们没有考虑到啊,这个情况就代表这整个前缀和就已经满足了所以mp[0]=1;
但是你这么改还是不对,那是因为!!!
sum[i]-i i很有可能大于sum[i]因此!!!要做一个基准点
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
ll sum[2102100];
int main(){
int T;
cin>>T;
while(T--){
ll n;
cin>>n;
getchar();
ll ans=0;
map<ll,ll>mp;
mp[100000]=1;
for(ll i=1;i<=n;i++){
char c;
cin>>c;
sum[i]=sum[i-1]+c-'0';
ans+=mp[sum[i]-i+100000];
mp[sum[i]-i+100000]++;
}
cout<<ans<<endl;
}
}