import java.util.Scanner;
public class code15_CountOfRangeSum {
//计算区间和的主方法
public static int countRangeSum(int[] nums, int lower, int upper) {
//如果数组为空的话直接返回值为0
if (nums == null || nums.length == 0) {
return 0;
}
//统计前缀和,生成前缀和数组 用long类型,防止溢出
//新建一个数组来存放前缀和
long[] sum = new long[nums.length];
//0——0的前缀和就是0位置上的数
sum[0] = nums[0];
//计算全部的前缀和
for (int i = 1; i < nums.length; i++) {
sum[i] = sum[i - 1] + nums[i];
}
//对前缀和数组,从0开始到最后利用归并排序,在merge的同时结算答案
return process(sum, 0, sum.length - 1, lower, upper);
}
// 返回preSumArr[L...R]上,区间累加和满足条件的个数
public static int process(long[] sum, int L, int R, int lower, int upper) {
//如果左边等于右边表示的是,前缀和中只有一个数
//所以如果这个数满足lower=<数<=upper 则返回1 否则返回0
if (L == R) {
return sum[L] >= lower && sum[L] <= upper ? 1 : 0;
}
//计算中点 >>表示右移一位 表示除以2取整
int M = L + ((R - L) >> 1);
//左区、右区分别递归,结算各自区间上的答案
int left = process(sum, L, M, lower, upper);
int right = process(sum, M + 1, R, lower, upper);
for (int i = 0; i < sum.length; i++) {
System.out.println(sum[i]);
}
//此时左区和右区已经分别有序,左右两区merge,结算左右整体的答案:
int merge = merge(sum, L, M, R, lower, upper);
// System.out.println(left);
// System.out.println(right);
// System.out.println(merge);
return left+right+merge;
}
// preSumArr[L...M] merge preSumArr[M+1...R]
// 左区merge右区,返回符合条件的个数
public static int merge(long[] arr, int L, int M, int R, int lower, int upper) {
int ans = 0;
//左右区互相归并
//定义窗口的左右边界
int windowL = L;
int windowR = L;
// [windowL, windowR)
//遍历右组的数 计算前缀和i位置中有多少值落在 【x-upper----x-lower】之间
for (int i = M + 1; i <= R; i++) {
//当前值-upper作为最小值
//当前值-lower作为最大值
long min = arr[i] - upper;
long max = arr[i] - lower;
//窗口左边界和右边界只会向右
while (windowR <= M && arr[windowR] <= max) {
windowR++;
}
//窗口左边界和右边界只会向右
while (windowL <= M && arr[windowL] < min) {
windowL++;
}
//每一步都累加到ans上面
ans += windowR - windowL;
}
//正常merge为了让其有序
//创建一个新的数组 以下是经典的归并排序的merge的代码
long[] help = new long[R - L + 1];
int i = 0;
int p1 = L;
int p2 = M + 1;
//归并的过程
while (p1 <= M && p2 <= R) {
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
//写回help数组
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
return ans;
}
//计算区间和
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next().toString();
String[] arr = s.split(",");
int[] nums = new int[arr.length];
for(int j = 0; j<nums.length;j++) {
nums[j] = Integer.parseInt(arr[j]);
// System.out.println(b[j]);
}
int a = sc.nextInt();
int b = sc.nextInt();
int sum = countRangeSum(nums, a, b);
System.out.println(sum);
}
}