题目分析:

1.我们要求的是区间(区间不能重叠)的最大值,这一点可以基于前缀和思想来求解,前缀和不仅编码快速而且可以让代码运行速度得到极大的提高
2.其次我们可以用动态规划思想动态的求解最优值,我们以i为分界线,把区间分为左半边与右半边,对于分开的区间我们分别用dp求出最优值,最后把两段区间最优值相加就是答案
3.由于数据比较大,所以我们需要用long long来定义变量和数组
4.答案可能出现负数,为了避免不必要的麻烦我们就把ans初始化为一个很小很小的数字

#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
typedef long long ll;
ll w[maxn], sum[maxn], a[maxn], b[maxn];
int main()
{
    ll t, n, k, ans;
    scanf("%lld", &t);
    while (t--)
    {
        ans = -1e18;
        memset(a, -inf, sizeof(a));
        memset(b, -inf, sizeof(b));
        scanf("%lld%lld", &n, &k);
        for (int i = 1; i <= n; ++i)
        {
            scanf("%lld", &w[i]);
            sum[i] = sum[i - 1] + w[i]; //求前缀和
        }
        for (int i = k; i <= n - k; ++i)
            a[i] = max(sum[i] - sum[i - k], a[i - 1]); //求i的左边
        for (int i = n - k + 1; i >= k + 1; --i)
            b[i] = max(sum[i + k - 1] - sum[i - 1], b[i + 1]); //求i的右边
        for (int i = k; i <= n - k; ++i)
            ans = max(ans, a[i] + b[i + 1]); //至于为什么要从k开始因为我们求的区间的长度就是k,如果从小于k开始那么就会越界了
        printf("%lld\n", ans);
    }
    return 0;
}