AT2412 最大の和

传送门

思路:

  线段树暴力枚举区间,查询最大区间和。

Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define lck_max(a,b) ((a)>(b)?(a):(b))
#define lck_min(a,b) ((a)<(b)?(a):(b))
typedef long long LL;
const int maxn=1e5+7;
const int INF=1e9+7;
LL n,k,ans=-INF,sum[maxn<<2],a[maxn];
inline LL read()
{
    LL kr=1,xs=0;
    char ls;
    ls=getchar();
    while(!isdigit(ls))
    {
        if(!(ls^45))
            kr=-1;
        ls=getchar();
    }
    while(isdigit(ls))
    {
        xs=(xs<<1)+(xs<<3)+(ls^48);
        ls=getchar();
    }
    return xs*kr;
}
inline void out(LL xs)
{
    if(!xs) {putchar(48); return;}
    if(xs<0) putchar('-'),xs=-xs;
    int kr[57],ls=0;
    while(xs) kr[++ls]=xs%10,xs/=10;
    while(ls) putchar(kr[ls]+48),ls--;
}
void build_sum(LL k,LL l,LL r)
{
    if(l==r) {sum[k]=a[l];return;}
    LL mid=l+r>>1;
    if(l<=mid) build_sum(k<<1,l,mid);
    if(mid<r) build_sum(k<<1|1,mid+1,r);
    sum[k]=sum[k<<1]+sum[k<<1|1];
}
LL query_sum(LL k,LL l,LL r,LL x,LL y)
{
    if(l>=x&&r<=y) return sum[k];
    //if(l>y||r<x) return 0;
    LL mid=l+r>>1,res=0;
    if(x<=mid) res+=query_sum(k<<1,l,mid,x,y);
    if(mid<y) res+=query_sum(k<<1|1,mid+1,r,x,y);
    return res;
}
int main()
{
    n=read();k=read();
    for(LL i=1;i<=n;i++) a[i]=read();
    build_sum(1,1,n);
    for(LL i=k+1;i<=n;i++)
        ans=lck_max(ans,query_sum(1,1,n,i-k+1,i));
    out(ans),putchar('
');
return 0;
}
原文地址:https://www.cnblogs.com/lck-lck/p/9904599.html