小b有一个01序列A,她想知道A有多少个非空连续子序列和为S。

你能帮帮她吗?

 收起

输入


第一行输入一个数n,表示A的长度; 第二行输入n个数‘0’或‘1’,表示A中的元素,以空格隔开; 第三行输入一个非负整数S; 其中0≤S≤n≤30000。


输出


输出一个数,表示子数组的个数


输入样例


5 1 0 1 0 1 2


输出样例


4


分析:

sum[r]-sum[l-1]==k,则对于每一个sum[i]统计其前面k-sum[i]的个数即可,注意最后加上sum[i]==k的情况。

扩展:

给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。  
你能求出数列中总共有多少个K倍区间吗?  

求区间[l,r]的和是k的倍数的个数。区间[l,r]的和是k的倍数即(sum[r] - sum[l-1])%k == 0 即sum[r]%k == sum[l-1]%k,即对于每一个sum[i]求sum[i]%k的个数即可,注意最后加上map[0]的情况
 

import java.util.HashMap;
import java.util.Scanner;




public class Main {
static Long [] x=new Long[30005];
static Long [] sum=new Long[30005];
static Long [] dp=new Long[505];

public static void main(String[] args) {
Scanner in=new Scanner(System.in);

int n=in.nextInt();

sum[0]=(long) 0;
HashMap<Long,Integer> map=new HashMap<>();
for(int i=1;i<=n;i++)
{
x[i]=in.nextLong();

}
Long k=in.nextLong();
Long ans=(long) 0;
for(int i=1;i<=n;i++)
{

sum[i]=sum[i-1]+x[i];
if(sum[i]==k)
{
ans++;
}
if(map.containsKey(sum[i]-k)==true)
{
ans+=map.get(sum[i]-k);
}


if(map.containsKey(sum[i]))
{
map.replace(sum[i], map.get(sum[i])+1);

}
else map.put(sum[i], 1);
}

System.out.println(ans);
System.gc();
}
}