思路:先求得一个东西:sum[i]表示从区间[ai...ai+k-1]的区间和,求到n-k+1就OK了,后面的没用;然后呢,搞一个结构体,这个结构体有id和val:分别对应就是i和sum[i];这个结构体按val排序;然后就可以干坏事了。。。。
先枚举左区间的开头,从1到n-2k+1,对于每一个左区间可用的右区间开头都至少要大于或等于i+k;然后因为按val排好了序,所以取的肯定是最大的区间值,判断最大的这个右区间是否可用,不可用就可以把他扔掉了,因为对于i都是不可用的,那么i+1,i+2...更加是不可用的,然后枚举完左区间开头不断更新最大值自然得到答案;

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 2e5+10;
typedef long long ll;
const ll inf = 1e18;
ll a[N],sum[N];//sum[i]表示以[i,i+k-1]的区间和,i最大n-k+1
int n,k;
struct Node{
    int id;
    ll val;
}P;
bool cmp(Node x,Node y){
    if(x.val != y.val) return x.val > y.val;
    else return x.id < y.id;
}
vector<Node> A;
int main(){
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        sum[1] = 0;A.clear();
        for(int i = 1;i <= n;i++) scanf("%lld",a+i);
        for(int i = 1;i <= k;i++) sum[1]+=a[i];
        for(int i = 2;i <= n-k+1;i++){
            sum[i] = sum[i-1] - a[i-1] + a[i+k-1];
        }
        int cnt = 0;
        for(int i = k+1;i <= n-k+1;i++){
            P.id = i;P.val = sum[i];
            A.push_back(P);
        }
        sort(A.begin(),A.end(),cmp);
        int idx = 0;
        ll ans = -inf; 
        for(int i = 1;;i++){
            if(i+2*k-1 > n) break;
            while(A[idx].id < i+k) idx++;
            if(ans < sum[i]+A[idx].val){
                ans = sum[i]+A[idx].val;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}