题解:
考察点: 滑动窗口,数形结合
易错点:
在本题中数据范围为,如果使用暴力求解是行不通的,因为如果使用复杂度为
的暴力,那运算次数将达到
,一般来说,在
时间范围内
所能抗住的运算次数在
解法:滑动窗口
首先,先从下图来观察出一个很重要的结论:
对于一个全由正整数构成的序列来说,如果区间中所有元素的和大于等于
,则区间
中所有元素的和一定大于等于
。这是一个非常显然的结论,但在这里却非常有用。假设位置
为区间
和
的分隔线,
中所有元素的和大于等于
,则当前位置
对答案的贡献为
,因为后面无论加上多少个元素,总可以,满足区间的和大于等于
。
有了上述结论,可以很自然使用滑动窗口算法来做这个问题。对于当前位置,指针
指向其所对应区间
的开头。如果
大于
,则指针
从
的开始位置往后移动,直到
所对应的区间小于
为止。同时指针每移动一次,
对答案的贡献增加
,因为其后的都满足大于等于
。整个过程中最多
遍历1次,
遍历一次,所以复杂度为
,也就是
级别的复杂度
#include "bits/stdc++.h"
using namespace std;
const int maxn=1e6+100;
typedef long long LL;
int n,a[maxn];
LL x;
int main()
{
scanf("%d%lld",&n,&x);
LL sum=0,ans=0;
int j=1;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
if(sum>=x){
ans+=n-i+1;
while(j<=i&&sum>=x){
sum-=a[j];
j++;
if(sum>=x) ans+=n-i+1;
else break;
}
}
}
printf("%lld\n",ans);
return 0;
} 
京公网安备 11010502036488号