问题描述:
A string is binary, if it consists only of characters "0" and "1".
String v is a substring of string w if it has a non-zero length and can be read starting from some position in string w. For example, string "010" has six substrings: "0", "1", "0", "01", "10", "010". Two substrings are considered different if their positions of occurrence are different. So, if some string occurs multiple times, we should consider it the number of times it occurs.
You are given a binary string s. Your task is to find the number of its substrings, containing exactly k characters "1".
InputThe first line contains the single integer k (0 ≤ k ≤ 10^6). The second line contains a non-empty binary string s. The length of s does not exceed 10^6 characters.
Output
Print the single number — the number of substrings of the given string, containing exactly k characters "1".
Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
Example1 1010
6
2 01010
4
100 01010
0
题目分析:连续子序列中1的个数为k等价于和为k,可以用前缀和来解决,k=0的时候特判一下
代码如下:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=1e6+100;
ll sum[maxn];
string str;
int main()
{
int k;
while (scanf("%d",&k)!=EOF) {
cin>>str;
sum[0]=0;
for (int i=0;i<str.size();i++) {
if (str[i]=='1') sum[i+1]=sum[i]+1;
else sum[i+1]=sum[i];
}
sum[str.size()+1]=sum[str.size()]+1;//设置哨兵
ll ans=0,cnt=0;
if(k == 0){
for(int i = 0; i < str.size(); ++i){
if(str[i] == '0') cnt++;
else{
ans += (ll)cnt * (cnt + 1) / 2;//所有连续子区间的个数
cnt = 0;
}
}
if(cnt){
ans += (ll)cnt * (cnt + 1) / 2;
}
cout << ans <<endl;
return 0;
}
for (int i=0;i<=str.size();i++) {
if (sum[i]+k>sum[str.size()]) break;
ans+=upper_bound(sum,sum+1+str.size()+1,sum[i]+k)-lower_bound(sum,sum+1+str.size()+1,sum[i]+k);
}
printf("%lld\n",ans);
}
return 0;
}