Let's implement a sliding window using two pointers, and . For each fixed i = 1, 2, ..., expand the interval as much as possible so that the sum of its elements does not exceed . In other words, for each , search for the largest possible such that the sum of elements in the interval does not exceed , while the sum of elements in the interval [i ... j + 1] exceeds .
Let be the sum of numbers in the interval . If s + a[j + 1] \le m, expand the interval to [i ... j + 1]. Otherwise, shrink it to [i + 1 ... j]. Count the number of intervals with a sum of .
Example
Let's examine the movement of the pointers for the given example.
i = 0, moves forward until the sum of the numbers in the interval exceeds x = 7. We stop at the interval , since the sum of the numbers in it is , while in the interval , the sum of the numbers is already .
i = 1, moves forward to . The sum of the numbers in the interval is , while in the interval , it is already .
i = 2, the considered interval is . The sum of the numbers in it is , but we cannot move the index forward because the sum of the numbers in the interval is , which is greater than x = 7.
i = 3, the considered interval is . The sum of the numbers in it is , but we cannot move the index forward because the sum of the numbers in the interval is , which is greater than x = 7.
i = 4, the considered interval is . The sum of the numbers in it is .
The number of subarrays with a sum of x = 7 is . They start at indices , and .
Algorithm realization
Declare an array.
#define MAX 200001
long long a[MAX];Read the input data.
scanf("%d %lld", &n, &x);
for (i = 0; i < n; i++)
scanf("%lld", &a[i]);Initially, set the current interval [i ... j] = [0; 0]. The sum of the numbers in this interval is s = 0.
s = j = 0;For each value of , sequentially process the intervals .
for (i = 0; i < n; i++)
{For the fixed left end of the interval , search for the largest such that the sum of elements in this interval does not exceed .
while ((j < n) && (s + a[j] <= x)) s += a[j++];If the sum of the numbers in the current interval equals , increase the desired subarray count by .
if (s == x) cnt++;Recompute the sum for the interval [i + 1 ... j].
s -= a[i];
}Print the answer.
printf("%lld\n", cnt);