Description
给出一个0101串,问该串的恰有kk个的子串数量,两个子串只要在该串中位置不同则视为不同
Input
第一行一整数kk,之后输入一个串s(1≤k,|s|≤106)s(1≤k,|s|≤106)
Output
输出满足条件的子串数
Sample Input
1
1010
Sample Output
6
Solution
k=0k=0时,统计该串连续00的个数即可,时,尺取,找到kk个后,假设右端点后面还有连续RR个,左端点后还有连续LL个,那么对答案的贡献即为(L+1)⋅(R+1)(L+1)⋅(R+1)
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1000005;
int k,pos[maxn];
char s[maxn];
int main()
{
scanf("%d%s",&k,s+1);
int n=strlen(s+1);
ll ans=0;
if(k==0)
{
for(int i=1;i<=n;i++)
if(s[i]=='0')
{
int num=1;
while(i<n&&s[i]==s[i+1])i++,num++;
ans+=(ll)num*(num+1)/2;
}
}
else
{
int l=1,r=1,num=0;
while(l<=n)
{
while(num<k&&r<=n)
{
if(s[r]=='1')num++;
r++;
}
if(num<k)break;
//printf("l=%d r=%d\n",l,r);
int L=1;
while(l<=n&&s[l]=='0')l++,L++;
int R=1;
while(r<=n&&s[r]=='0')r++,R++;
//printf("L=%d R=%d\n",L,R);
ans+=(ll)L*R;
if(l>n||r>n)break;
l++,num--;
}
}
printf("%I64d\n",ans);
return 0;
}