思路

注意到这里是求某段区间的和,而且不修改,那肯定是用前缀和了 sum[ n ]表示 图片说明

接下来就是要选择两个长度为k的区间求最大,最原始的思路当然是枚举每个可能的区间更新最大值,代码就是

 ll ans = 0;
       for(int i = k ; i <= n-k ; ++i){
            for(int j = i+k ; j <= n ; ++j){
                ans = max(ans,a[i]-a[i-k] + a[j] - a[j-k]);
            }
       }

结果当然是T的果断,那肯定要想想怎么优化。
如果 两段区间分别是 (L,L+1,.....L+k) (R,R+1,.....,R+k)
假设 X为 两个区间的中间点,既 X >= L+k && X <= R
如果要取得最优解的话必定要满足区间 (L,L+1,.....L+k)为 1 ~ X 上 和最大和的区间,(R,R+1,.....,R+k) 为X ~ n 上最大和的区间,于是我们可以这样想,不断枚举 X的值 寻找 这样的两个区间。
那代码就出来了,结合代码理解一下吧

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
ll a[200005];
int main(){
   int t = read();
   while(t--){
       int n = read(),k = read();
       for(int i = 1 ; i <= n ;++i){
           a[i] = read();
           a[i] += a[i-1];
       }
       ll ans = -1e18,last = -1e18;
       for(int i = k ; i+k <= n ; ++i){
        last = max(last , a[i] - a[i-k]); //last表示 1 ~ i内最优的区间
        ans = max(ans , last + a[i+k] - a[i]);
       }
       cout<<ans<<endl;
   }
}