Codeforces(D. The Best Vacation)

在这里插入图片描述
昨晚的C题耽误了太多时间了,用了一个多小时才A掉,前期推式子推不出来,到最后打了个表一眼就看出规律了(懊悔了一晚上,早打表就好了)
D题是以每个月的最后一天为x的结尾,然后枚举即可,再加上一个前缀和计算。
代码:

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

ll a[400005];
ll sum[400005],s[400005],f[400005],all[400005];
int main()
{
    
    
    ll n,x;
    scanf("%lld %lld",&n,&x);
    for(int i=1;i<=n;i++)
    {
    
    scanf("%lld",&a[i]);}
    for(int i=n+1;i<=2*n;i++)
    {
    
    a[i]=a[i-n];}
    for(int i=2*n;i>=1;i--)
    {
    
    s[i]=s[i+1]+a[i];}
    for(int i=1;i<=2*n;i++)
    {
    
    
        sum[i]=sum[i-1]+a[i];
        f[i]=s[2*n-i+1];
        all[i]=all[i-1]+a[i]*(a[i]+1)/2;
    }
    ll ans=-1;
    for(int i=1;i<=2*n;i++)
    {
    
    
        if(x<=a[i])
        {
    
    
            ll u=a[i]-x;
            ll e=a[i]*(a[i]+1)/2-u*(u+1)/2;
            ans=max(ans,e);
            continue;
        }
        ll sx=x-a[i];
        ll ssx=sx+(sum[2*n]-sum[i-1]);
        ll pos=lower_bound(f+1,f+1+2*n,ssx)-f;
        pos=2*n-pos+1;
        if(pos==0)
        {
    
    
            ll e=all[i];
            ans=max(ans,e);
        }
        if(pos!=0)
        {
    
    
            ll ce=all[i]-all[pos];
            ll qj=sum[i]-sum[pos];
            sx=sx-qj+a[i];
            if(sx==a[pos])
            {
    
    ll e=ce+(all[pos]-all[pos-1]);
            ans=max(ans,e);}
            if(sx<a[pos])
            {
    
    
                ll u=a[pos]-sx;
                ll e=ce+a[pos]*(a[pos]+1)/2-u*(u+1)/2;
                ans=max(ans,e);
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/106378588