NCS
题目描述
某巨魔有条长度为
N
的由红色头骨和绿色头骨组成的项链(当然事实上是没有的),这条项链现在已经断开了。
由于这条项链太长了,巨魔想截取其中一段长度非零的项链作为自己的新项链。
这个巨魔很迷信,它认为截取下来的项链段上如果有正好
它想知道有多少种截取方法使得截下来的项链利于报复社会。
两种截取方法被认为不同当且仅当它们至少有一个截取的位置不同。
当然,巨魔也可以保留这条项链,不截取。
输入格式
第一行一个数字
M
。
第二行一个01字符串,
输出格式
输出一行,即截下来的项链有利于报复社会的截取方案数。
样例输入
1
1010
样例输出
6
样例解释
截取方案:[1,1],[1,2],[2,3],[2,4],[3,4],[3,3]。总共 6 种。
数据范围
30%
的数据:
1≤N≤1000
。
100%
的数据:
1≤N≤1000000
。
0≤M≤1000000
。
Solution
求出前缀和
x[i]
和 前缀和等于
k
的位置的数量
则对于前缀和为
x[i]
的位置
i
,以它为右端点的截取方案的个数为
注意考虑
m=0
的情况。
Code
#include <iostream>
#include <cstdio>
#define Min(x,y) ((x)<(y)?(x):(y))
using namespace std;
int m,ans,i;
int w[1000010];
int s[1000010];
int ss[1000010];
int main(){
freopen("nichs.in","r",stdin);
freopen("nichs.out","w",stdout);
scanf("%d",&m);
ss[0]=1;
while(scanf("%1d",&w[++i])!=EOF){
s[i]=s[i-1]+w[i];
if(s[i]>=m)ans+=ss[s[i]-m];
if(s[i]==s[i-1])ss[s[i]]++;
else ss[s[i]]=1;
}
printf("%d\n",ans);
return 0;
}