Codeforces Round #645 (Div. 2) D - The Best Vacation 题解(二分+思维)

题目链接

题目大意

一年有n个月,每个月有d[i]天,让你找出连续x天,使其日期的总和最大,可以跨年

题目思路

这里要发现一个性质:即连续的x天一定满足最后一天在月份的结尾,结论是显然的。
然后用两个前缀和,然后二分,二分的方法是二分差值值得学习

代码

#include
#include
#include
#include
#include
const int maxn=4e5+5;
using namespace std;
typedef long long ll;
ll n,x,d[maxn],prea[maxn],preb[maxn],ans;
int main(){
    scanf("%lld %lld",&n,&x);
    for(int i=1;i<=n;i++){
        scanf("%lld",&d[i]);
        d[n+i]=d[i];
    }
    n=n*2;
    for(int i=1;i<=n;i++){
        prea[i]=prea[i-1]+d[i];
        preb[i]=preb[i-1]+d[i]*(d[i]+1)/2;
    }
    for(int i=1;i<=n;i++){
        if(prea[i]>=x){
            int pos=lower_bound(prea+1,prea+1+n,prea[i]-x)-prea;
            ll cha=x-(prea[i]-prea[pos]);//还有cha天不完整,在pos月的最后cha天
            ll sum=(preb[i]-preb[pos])+(d[pos]+d[pos]-cha+1)*cha/2;
            ans=max(sum,ans);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(思维)