Good Subarrays(思维)
题意:找给定串中满足\(\sum_{i=l}^{r}a_{i}=\left ( r-l+1\right )\)的子串的个数
题解:式子转换:
\(\sum_{i=l}^{r}a_{i}=\left ( r-l+1\right )\)连边同时减去\(\left ( r-l+1\right )\)
得:\(\sum_{i=l}^{r}\left ( a_{i}-1\right )=0\);所以只需要找区间和为\(0\)得个数
对于前缀和:如果\(sum\left [ i\right ]==sum\left [ j\right ]\),则\(\left ( i,j\right ]\)之间的子串之和为\(0\)
AC_Code:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef long double ld; 5 #define endl '\n' 6 const int inf=0x3f3f3f3f; 7 const int maxn=1e5+10; 8 const int maxm=5e5+10; 9 const int mod=1e9+7; 10 11 map<ll,ll>mp; 12 string s; 13 int n; 14 ll sum[maxn],ans; 15 int main() 16 { 17 int t; cin>>t; 18 while( t-- ){ 19 cin>>n>>s; 20 sum[0]=0; ans=0; mp.clear(); 21 22 mp[0]++;//1-1=0,某个位置为1它自己就可以 23 for(int i=0;i<n;i++){ 24 sum[i+1]=sum[i]+(s[i]-'0')-1; 25 mp[sum[i+1]]++; 26 } 27 for(int i=0;i<=n;i++){ 28 if( mp[sum[i]] ) ans+=(mp[sum[i]])*(mp[sum[i]]-1)/2; 29 mp[sum[i]]=0; 30 } 31 cout<<ans<<endl; 32 } 33 return 0; 34 }