赞
踩
题目
题意:给定n个数,每个数大小为0-9,求这n个数,有多少个连续子区间,满足
∑
i
=
l
r
=
=
(
r
−
l
+
1
)
\sum_{i=l}^{r}==(r-l+1)
∑i=lr==(r−l+1)
思路:每个数都减去1,问题转化为,求有有多少个连续子区间,满足 ∑ i = l r = = 0 \sum_{i=l}^{r}==0 ∑i=lr==0,只需求出每个前缀和,如果 s u m i = 1 l = = s u m i = 1 r sum_{i=1}^l == sum_{i=1}^r sumi=1l==sumi=1r,说明 s u m i = l + 1 r = = 0 sum_{i=l+1}^{r} == 0 sumi=l+1r==0。因此,找出所有前缀和相同的个数x,那么这些前缀和贡献的区间数为 x ∗ ( x − 1 ) / 2 x*(x-1)/2 x∗(x−1)/2,注意,初始时, n u m 0 = 1 num_0=1 num0=1
#include<bits/stdc++.h> using namespace std; #define ll long long const int maxn = 100010; int a[maxn]; char s[maxn]; int n; unordered_map<int, int> mp; int main() { int t; scanf("%d", &t); while(t--) { scanf("%d", &n); scanf("%s", s); a[0] = 0; mp.clear(); ++mp[0];// 初始时,mp[0]=1 for(int i = 1;i <= n; ++i) { a[i] = a[i-1] + s[i-1] - '0' - 1; ++mp[a[i]]; } ll ans = 0; for(auto it: mp) { ans += 1LL * it.second * (it.second - 1) / 2; } printf("%lld\n", ans); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。