#include<bits/stdc++.h>
using namespace std;
int main( )
{
//转化为递增的前缀和
int n,m;
cin>>n>>m;
long long a[300000]={0};
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]+=a[i-1];
}
deque<long long>q;//存下标
long long s=-1000000;//注意可能最大伤害是负数,哈哈,真是,没能掉血,还能补血,好东西
q.push_back(0);
for(int i=1;i<=n;i++){
if(!q.empty()&&q.front()<i-m)q.pop_front();//保证滑动窗口的大小最大为m
s=s>a[i]-a[q.front()]?s:a[i]-a[q.front()];//求窗口的最大值
while(!q.empty()&&a[q.back()]>=a[i])q.pop_back();//保证单调
q.push_back(i);
// for(int j=0;j<q.size();j++){
// cout<<q[j]<<' ';
// }
// cout<<endl;
}
cout<<s;
return 0;
}
deque常用函数
构造函数
deque<T> dq;:默认构造函数,创建一个空的双端队列。
deque<T> dq(n, value);:创建一个包含 n 个元素,且每个元素都初始化为 value 的双端队列。
deque<T> dq(begin, end);:使用迭代器范围 [begin, end) 初始化双端队列。
添加元素
dq.push_back(value);:在队列尾部添加元素 value。
dq.push_front(value);:在队列头部添加元素 value。
删除元素
dq.pop_back();:删除队列尾部的元素。
dq.pop_front();:删除队列头部的元素。
访问元素
dq.front();:返回队列头部的元素。
dq.back();:返回队列尾部的元素。
dq[index];:通过索引访问元素。
大小和容量
dq.size();:返回队列中元素的数量。
dq.empty();:检查队列是否为空。
dq.clear();:清空队列中的所有元素。
其他操作
dq.insert(position, value);:在指定位置插入元素。
dq.erase(position);:删除指定位置的元素。
dq.assign(n, value);:用 n 个 value 元素替换当前队列的内容。
单调队列
单调队列是一种特殊的数据结构,通常用于解决一些需要维护元素顺序的问题,特别是在滑动窗口或区间查询的场景中。单调队列可以分为单调递增队列和单调递减队列。
常用代码
deque<int> dq; // 双端队列
void push(int value) {
// 移除队列中所有小于当前值的元素
while (!dq.empty() && dq.back() < value) { //保证单调
dq.pop_back();
}
dq.push_back(value);
}
// 移除元素
void pop(int value) {
// 如果弹出的元素是最大值,则从队列中移除
if (!dq.empty() && dq.front() == value) { //可以用来处理窗口大小
dq.pop_front();
}
}
// 获取当前最大值
int max() const {
return dq.front(); // 队列的前端是当前窗口的最大值
}
应用场景
- 滑动窗口最大值/最小值:在给定数组中,计算每个滑动窗口的最大值或最小值。
- 区间最值查询:在动态数组中快速查询某个区间的最值。
今天就到这里啦,我们明天再见,✌