哈哈哈做题好快乐!!!
思路:
一开始我会想到求好所有区间的前缀和,然后O(n^2)的枚举更新最大值即可。这样铁定超时。
然后我就会这样想把所有区间和存起来然后降序,然后取第一个最大值,然后去找不与他重复的第二大值,时间复杂度O(nlogn)时间复杂度应该没问题,不过这样也是错的,因为有可能取了第一大值,然后第2,3大都与它有重复部分,你只能取第4大,然后可能第2,3大的值更优。所有这样也错了。
最后我们会发现区间和的值是不会被更新的,所以我们可以先预处理[i,n]的最大值,然后枚举所有区间直接取与它不重复部分的最大值,然后不断更新答案即可。
代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
const int maxn = 1e6 + 10;
const ll inf = 0x3f3f3f3f;
ll a[maxn],sum[maxn],ans[maxn],Max[maxn];
void solved(){
    int t;cin>>t;
    while(t--){
        int n,k;cin>>n>>k;
        for(int i = 1; i <= n; i++){
            cin>>a[i];
            sum[i] = sum[i - 1] + a[i];
        }
        int cnt = 1;
        for(int i = 1; i + k - 1 <= n; i++){
            ans[cnt++] = sum[i + k - 1] - sum[i - 1];
        }
        for(int i = 1; i <= maxn - 10; i++)Max[i] = -1e18;
        for(int i = cnt - 1; i >= 1; i--){
            Max[i] = max(ans[i],Max[i + 1]);
        }
        ll res = -1e18;
        for(int i = 1;i + k < cnt; i++){
            res = max(res,ans[i] + Max[i + k]);
        }
        cout<<res<<endl;
    }
}
int main(){
    solved();
    return 0;
}