题目链接:Codeforces Round #112 (Div. 2) C Another Problem on Strings
题意:给出一个只含0,1的序列,求序列中和为n的子序列有多少个。
思路:预处理出序列的前缀和,然后枚举序列时,记录(vis)该位置之前已有的前缀和,再查询(sum[i]-n)的个数,即以该位置为结束的子序列和为n的个数。
注意:vis数组中0应该始终存在,初始化vis[0]=1(why?,因为sum[i]本身就等于n算一个方法数)。
举一反三:类似的就已经可以得到,任意序列中和为n的子串有多少个的O(n的算法。
如有不妥之处,欢迎指正!
AC代码:
#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#define LL __int64
using namespace std;
string str;
LL sum[1000010];
LL vis[1000010];
int main()
{
LL n,len,i;
while(cin>>n){
cin>>str;
memset(vis,0,sizeof vis);
len=str.length();
vis[0]=1;
for(i=0;i<len;i++){
if(i==0) sum[i]=str[i]-'0';
else sum[i]=sum[i-1]+str[i]-'0';
}
LL ans=0;
for(i=0;i<len;i++){
if(sum[i]>=n){
LL u=sum[i]-n;
ans+=vis[u];
}
vis[sum[i]]++;
}
printf("%I64d\n",ans);
}
return 0;
}