You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 300010 ;
const int INF = 0x3f3f3f3f ;
int n , m ;
int q [ N ] ;
// 单调队列, 本质记录的是下标序号, 因为只有记录了下标, 才能知道是否离i的距离长度超过m了没有。
// 同时, 记录了下标的话, 想要其它的信息都是可以表示出来的, 比如s[q[hh]]
int s [ N ] ; // 前缀和
int res = - INF ; // 预求最大,先设最小
int main ( ) {
cin > > n > > m ;
for ( int i = 1 ; i < = n ; i + + ) cin > > s [ i ] , s [ i ] + = s [ i - 1 ] ; // 前缀和
int hh = 0 , tt = 0 ; // 等价于增加了一个哨兵节点,也就是把下标为0的前缀和s[0]=0加入了滑动窗口中, 描述1号节点向前m个节点的前缀和最小值是0
// 枚举右边界
for ( int i = 1 ; i < = n ; i + + ) {
// 1、老掉牙的需要去世
while ( hh < = tt & & q [ hh ] < i - m ) hh + + ;
// 2、此时单调队列中保存就是i以前、长度最长为m的单调上升的一个序列, 队列头保存的就是i前面前缀和的最小值
// 此时i还没有进入队列, 单调队列其实在枚举数字i的左侧
res = max ( res , s [ i ] - s [ q [ hh ] ] ) ;
/*
把0, 也就是sum(0)塞入队列中( 这是给sum( 1) 用的, 因为可能sum( 1) -sum( 0) 就是最大的子序列, 不加这个0就没法计算了) , 最小值为0
*/
// 3、i入队列
// 比i老没它小的都去死吧~
while ( hh < = tt & & s [ q [ tt ] ] > = s [ i ] ) tt - - ;
// i入队列,本轮结束
q [ + + tt ] = i ;
}
// 输出结果
cout < < res < < endl ;
return 0 ;
}