The land is for sale in CyberCity, and is divided into several pieces. Here it is assumed that each piece of land has exactly two neighboring pieces, except the first and the last that have only one. One can buy several contiguous(连续的) pieces at a time. Now given the list of prices of the land pieces, your job is to tell a customer in how many different ways that he/she can buy with a certain amount of money.
Input Specification:
Each input file contains one test case. Each case first gives in a line two positive integers: N (≤104), the number of pieces of the land (hence the land pieces are numbered from 1 to N in order), and M (≤109), the amount of money that your customer has.
Then in the next line, N positive integers are given, where the i-th one is the price of the i-th piece of the land.
It is guaranteed that the total price of the land is no more than 109.
Output Specification:
For each test case, print the number of different ways that your customer can buy. Notice that the pieces must be contiguous.
Sample Input:
5 85
38 42 15 24 9
Sample Output:
11
Hint:
The 11 different ways are:
38
42
15
24
9
38 42
42 15
42 15 24
15 24
15 24 9
24 9
/*
* =====================================================================================
* 题目大意:
*
* 一块地被分成 N 块,从左到右编号为 1 到 N,排成一列。
* 每块地有一个价格。客户有 M 元钱,想购买土地。
*
* 购买规则:
* - 只能购买**连续的一段**地块(例如第 2 到第 4 块)。
* - 可以只买一块,也可以买多块,但必须是连续的。
* - 总花费不能超过 M。
*
* 任务:计算有多少种不同的购买方式(即不同的连续子段),使得总价 ≤ M。
* 注意:即使价格相同,只要位置不同,就算不同的方案。
*
* 输入格式:
* - 第一行:N(地块数,≤10^4)和 M(预算,≤10^9)
* - 第二行:N 个正整数,表示每块地的价格
* - 保证所有地块总价 ≤ 10^9
*
* 输出格式:
* - 一个整数,表示合法的购买方式总数。
*
* 示例:
* 输入:5 85
* 38 42 15 24 9
* 输出:11
*
* =====================================================================================
* 解题思路:
*
* 方法:双指针(滑动窗口)—— O(N) 时间复杂度
*
* 核心思想:
* 使用两个指针 left 和 right,维护一个窗口 [left, right],表示当前考虑的连续地块。
* 枚举右端点 right,同时动态调整左端点 left,使得窗口内总价格 ≤ M。
*
* 关键观察:
* 对于固定的右端点 right,如果 [left, right] 的和 ≤ M,
* 那么以 right 结尾的所有合法子数组为:
* [left, right], [left+1, right], ..., [right]
* 共有 (right - left + 1) 种。
*
* 算法步骤:
* 1. 初始化 left = 0, sum = 0, count = 0
* 2. 枚举 right 从 0 到 N-1:
* - 将 prices[right] 加入当前窗口(sum += prices[right])
* - 若 sum > M,则不断移动 left 指针,直到 sum ≤ M
* - 此时以 right 结尾的合法方案数为 (right - left + 1),加到 count
* 3. 返回 count
*
* 时间复杂度:O(N) —— 每个元素最多被左右指针各访问一次
* 空间复杂度:O(N) —— 存储价格数组
*
* =====================================================================================
*/
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] firstLine = br.readLine().split("\\s+");
int N = Integer.parseInt(firstLine[0]);
int M = Integer.parseInt(firstLine[1]);
String[] priceLine = br.readLine().split("\\s+");
int[] prices = new int[N];
for (int i = 0; i < N; i++) {
prices[i] = Integer.parseInt(priceLine[i]);
}
long count = 0; // 方案总数(用 long 防止溢出)
long sum = 0; // 当前窗口的总价格
int left = 0; // 滑动窗口左指针
// 双指针遍历
for (int right = 0; right < N; right++) {
sum += prices[right]; // 扩展右边界
// 如果当前窗口总和超过预算,收缩左边界
while (sum > M && left <= right) {
sum -= prices[left];
left++;
}
// 此时 [left, right] 内所有以 right 结尾的子数组都合法
if (sum <= M) {
count += right - left + 1;
}
}
System.out.println(count);
br.close();
}
}