D. The Best Vacation(二分)

题目传送门

题意: 我们用一种新的纪年方式,一年有n个月,每个月有a[i]天,没有闰年。现在给出计算某一天的代价的方式为该天在该月中是第几天。我们要连续选择x天,要求这x天得到的价值最大。(这x天并不一定要在同一年内,即可以选择上一年的末尾以及本年开头这样拼接),保证x要小于一整年的天数。

思路: 假设我们已经选取了某一段连续的月份,还剩下一些,可以向前选择某一个月的月末,还可以向后选择某一个月的月初,那么肯定是选择月末更加划算,因为同样花费1天,获得的代价肯定是月末的多。所以我们知道答案一定是以某个月的某个节点开始,到某个月的月末结束,这样的一段才会价值最大。所以我们先把两年拼接起来,然后枚举右端点R,二分查找左端点L,这个即找到一个最小的L,使得sum[R]-sum[L]<=x。(这个sum计算的是天数前缀和。)我们再用一个sumb记录代价的前缀和,节省计算代价所花的时间。

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=4e5+5;
const int inf=0x7fffffff;
const int mod=998244353;
const double eps=1e-6;
const double PI=acos(-1);
int a[N],b[N],suma[N],sumb[N];
signed main()
{
    int n,x;
    cin>>n>>x;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=(1+a[i])*a[i]/2;//当月代价
        suma[i]=suma[i-1]+a[i];
        sumb[i]=sumb[i-1]+b[i];
    }
    for(int i=1;i<=n;i++)//两年拼接
    {
        a[i+n]=a[i];
        b[i+n]=b[i];
        suma[i+n]=suma[i-1+n]+a[i+n];
        sumb[i+n]=sumb[i-1+n]+b[i+n];
    }
    int res=-inf;
    for(int i=1;i<=n*2;i++)
    {
        if(suma[i]<x)
            continue;
        int p=lower_bound(suma+1,suma+2*n+1,suma[i]-x)-suma;
        int t=sumb[i]-sumb[p];//代价计算
        t+=(a[p]+a[p]-(suma[p]-suma[i]+x)+1)*(suma[p]-suma[i]+x)/2;
        //x比suma[i]-suma[p]多出的那部分的天数贡献的代价。
        res=max(res,t);
    }
    cout<<res<<endl;
}

猜你喜欢

转载自blog.csdn.net/Joker_He/article/details/106381352