【每日一题】数学考试

数学考试

https://ac.nowcoder.com/acm/problem/15553

soltion

我们可以预处理出一个L数组,其中表示以i为右端点的长度为k的区间和。然后预处理一个数组表示以i为左端点的长度为k的区间和。这两个数组都可以通过预处理前缀和然后相减的方法得到。即:记为区间的数字和,那么区间的数字和就是

然后考虑如何找到两个最大的不相交的长度为k的区间,很容易想到对做一个前缀最大值,对做一个后缀最大值。然后枚举一下左边区间的右端点,找到右边区间中的最大值就可以保证两个区间不相交了。

单组数据复杂度

注意因为输入有负数,所以赋的初值应为极小值而不是0.

code

/*
* @Author: wxyww
* @Date: 2020-04-02 14:08:41
* @Last Modified time: 2020-04-02 14:16:44
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 200010;
ll read() {
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
ll a[N],L[N],R[N];
int main() {
    int T = read();
    while(T--) {
        int n = read(),k = read();
        memset(L,-0x3f,sizeof(L));
        memset(R,-0x3f,sizeof(R));
        for(int i = 1;i <= n;++i)
            a[i] = a[i - 1] + read();
        for(int i = k;i <= n;++i)
            L[i] = max(L[i - 1],a[i] - a[i - k]);
        for(int i = n - k + 1;i >= 1;--i)
            R[i] = max(R[i + 1],a[i + k - 1] - a[i - 1]);
        ll ans = -1e15;
        for(int i = k;i + k <= n;++i)
            ans = max(ans,L[i] + R[i + 1]);
        cout<<ans<<endl;
    }
    return 0;
}
全部评论

相关推荐

10-24 13:36
门头沟学院 Java
Zzzzoooo:更新:今天下午有hr联系我去不去客户端,拒了
点赞 评论 收藏
分享
ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务