题解(带解释)
2025-05-31 15:17:00
发布于:江西
15阅读
0回复
0点赞
前面输入+前缀和就不解释
遍历过程:
- 对于每个位置,首先检查队列头部元素是否超出窗口范围,如果超出则移动指针。
- 计算以当前位置为右端点的最大子数组和,并更新。
- 维护队列的单调性,从队列尾部开始移除所有大于等于当前前缀和的元素,通过移动指针实现。
- 最后将当前位置加入队列,即de[j++]=i
最后:时间复杂度:
# include <bits/stdc++.h>
typedef unsigned long long ull;
#define getchar getchar_unlocked()
#define putchar putchar_unlocked
#define psbc push_back
#define vco vector
using namespace std ;
const int MX=5e5;
int i,j,k;
int r(){
int x=0,f=1;
char c=getchar;
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar;}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^(3<<4)),c=getchar;
return x*f;
}
void w(int x){
if(x<0) putchar('-'),x=~(x-1);
else if(x>9) w(x/10);
putchar(x%10+'0');
}
int de[MX];
int main ( )
{
int n,m;
cin>>n>>m;
vco<int>a(n+1),s(n+3);
for(i=1;i<=n;i++){
a[i]=r();
s[i]=s[i-1]+a[i];
}
int l=0;
int maxi=0;
for(i=0;i<=n;i++){
while(l<j&&de[l]<i-m) l++;
if(l<j) maxi=max(maxi,s[i]-s[de[l]]);
while(l<j&&s[de[j-1]]>=s[i]) j--;
de[j++]=i;
}
cout<<maxi;
return 0;
}
这里空空如也
有帮助,赞一个