首先想到雙指針掃描,但雙指針最差2×N複雜度,而答案最大可以是N^2,直接求和掃描得到的結果一定會漏掉。
由於都是正整數,所以,對於剛掃到的某個區間[a, b],如果是合法的,那麼就是以b爲結尾合法區間中和
最大的一個區間,則以a+1~b爲區間左端點的區間都是合法的,所以,對於掃到的合法區間要累加 b - a + 1。
#include<bits/stdc++.h>
const int N = 1e5 + 10;
typedef long long ll;
using namespace std;
int num[N];
void run()
{
int n, p;
ll ans = 0;
int sum = 0;
scanf("%d%d", &n, &p);
for (int i = 0; i < n; i++)
scanf("%d", num + i);
int l = 0;
for (int i = 0; i < n; i++)
{
sum += num[i];
if (sum <= p)//當前位置加了後,統計以i爲區間右端點的合法區間數
ans += i - l + 1;
else
{
while (l <= i && sum > p)//l要直到i,因爲可能本身就是大於p的。
{
sum -= num[l];
l++;
}
//如果l>i這裏會加0,不影響答案,如果l<=i則sum<p成立,
//統計i爲右端點的合法區間數
ans += i - l + 1;
}
}
printf("%lld\n", ans);
}
int main()
{
int T, cas = 1;
scanf("%d", &T);
while (T--)
{
printf("Case #%d: ", cas++);
run();
}
return 0;
}