给定序列,求出最长的子段,满足其每个前缀和+s都大于等于0,s是给定的常数。
双指针:
对于每个l,求出其满足条件的最远的r,用于更新答案,
此时sum+a[r+1] +s < 0
.
我们再把l右移一格,继续求最远的r。这样是不会损失最优解的,原因如下:
l移动前,如果a[l]小于等于0,那么r接下来继续右移并更新答案即可;
如果a[l]大于0,移动后一定有[l+1,r+1]+s<0
,所以r不会右移,l会继续右移,而这个l贡献的答案一定小于移动前贡献的答案,所以不会损失最优解。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int maxn = 2e5+7;
int n,s;
int a[maxn];
//给定序列 求最长的子段满足 每个前缀和都大于等于给定的s*-1
//双指针
//对于l 求出最远的满足条件的r 更新答案 此时ret+a[r+1]-s < 0
//l右移一位 此时是满足双指针单调性的:
//如果a[l]小于等于0 那么r接下来继续右移即可
//如果a[l]大于0 由于[l+1,r+1]必定小于0 r会继续右移 为什么不考虑[l+1,r]的答案呢?因为一定小于r-l+1
int main()
{
int t;cin>>t;
while(t--)
{
scanf("%d %d",&n,&s);
for(int i=1;i<=n;i++) scanf("%d",a+i);
int al=0,ar=-1,l=1,r=1