Educational Codeforces Round 93 (Rated for Div. 2) C. Good Subarrays ###K ###K ###K//K
题目链接:https://codeforc.es/contest/1398/problem/C
题意:给定一个序列由0~9组成 定义 好子序列 为 长度等于其元素和 的序列,问有多少个好子序列
思路:因为要o n 过完,所以先考虑边跑边处理, 也就是走到某一个点的时候要能知道前面有多少是满足的
那么考虑用map和前缀和来记录前面的状态 然后就考虑 后面要如何累加前面的
但是一个好子序列的和是不确定的,所以必须要通过处理使得确定下来才能记录, 考虑到一段的平均值为1
那么把把每个数都-1 那么和为0的即是满足要求的 确定的值了
也就是现在只需要找出序列中哪些段和为0即可, 那么维护一个前缀和,sum 为0的时候满足,当sum不为0的时候 就要考虑前面有没有和这个sum一样的数
如果有的话,这两个前缀和相减 也是一段为0的子序列
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define pb push_back 6 const int maxn=1e5+10; 7 const int mod=1e9+7; 8 char s[maxn]; 9 10 11 12 int main() 13 { 14 ios::sync_with_stdio(false); 15 cin.tie(0); 16 int t; 17 cin>>t; 18 while(t--) 19 { 20 int n; 21 cin>>n; 22 cin>>(s+1); 23 ll ans=0; 24 map<ll,ll>mp; 25 ll sum=0; 26 for(int i=1;i<=n;i++) 27 { 28 int x=s[i]-'0'-1; 29 sum+=x; 30 if(sum==0) 31 ans++; 32 ans+=mp[sum]; 33 mp[sum]++; 34 } 35 cout<<ans<<'\n'; 36 } 37 38 39 40 41 }
也可以根据题意推得公式 sum[r]-sum[l-1]=r-l+1 等价于 sum[r]-r=sum[l-1]-(l-1) 那么也就是去找每个坐标之前有多少个sum-i 是一样的即可
根据实际意义 l=1的时候也是可以满足的 sum[i]-i==0 时额外+1即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define pb push_back 6 const int maxn=1e5+10; 7 const int mod=1e9+7; 8 char s[maxn]; 9 10 11 12 int main() 13 { 14 ios::sync_with_stdio(false); 15 cin.tie(0); 16 int t; 17 cin>>t; 18 while(t--) 19 { 20 int n; 21 cin>>n; 22 cin>>(s+1); 23 ll ans=0; 24 map<ll,ll>mp; 25 ll sum=0; 26 for(int i=1;i<=n;i++) 27 { 28 int x=s[i]-'0'; 29 sum+=x; 30 ll temp=sum-i; 31 if(temp==0) 32 ans++; 33 ans+=mp[temp]; 34 mp[temp]++; 35 } 36 cout<<ans<<'\n'; 37 } 38 39 40 41 42 }

浙公网安备 33010602011771号