Codeforces Round #645 (Div. 2) D. The Best Vacation
You've been in love with Coronavirus-chan for a long time, but you didn't know where she lived until now. And just now you found out that she lives in a faraway place called Naha.
You immediately decided to take a vacation and visit Coronavirus-chan. Your vacation lasts exactly x days and that's the exact number of days you will spend visiting your friend. You will spend exactly x consecutive (successive) days visiting Coronavirus-chan.
They use a very unusual calendar in Naha: there are n months in a year, i-th month lasts exactly di days. Days in the i-th month are numbered from 1 to di. There are no leap years in Naha.
The mood of Coronavirus-chan (and, accordingly, her desire to hug you) depends on the number of the day in a month. In particular, you get j hugs if you visit Coronavirus-chan on the j-th day of the month.
You know about this feature of your friend and want to plan your trip to get as many hugs as possible (and then maybe you can win the heart of Coronavirus-chan).
Please note that your trip should not necessarily begin and end in the same year.
Input
The first line of input contains two integers n and x (1≤n≤2⋅105) — the number of months in the year and the number of days you can spend with your friend.
The second line contains n integers d1,d2,…,dn, di is the number of days in the i-th month (1≤di≤106).
It is guaranteed that 1≤x≤d1+d2+…+dn.
Output
Print one integer — the maximum number of hugs that you can get from Coronavirus-chan during the best vacation in your life.
题意
给出n(有几个月),x(要选多少天),选择连续的x天(可从尾->头),求最大贡献
思路
考虑到是求给定范围内的贡献,所以采用前缀和+二分的思想来解决问题
1.开2*n大小的数组,然后依次对天数和每月的贡献求前缀和
2.因为要求选定天数内的最大贡献,要使选定天数内有最大贡献,则一定含有某个月的后几天
比如说:1 2 3 4 5 要求3天内的最大贡献那么一定选择的是这个月内的3 4 5 贡献为3+4+5=12
3.选择从末尾开始枚举终止月,在枚举的过程中low=a[i]-x,表示我还需要low天才能 满足共x天
解释for内循环:
lower_bound寻找low的时候返回的是大于等于low的值
当等于low时直接更新ans
当大于low时,证明a[i]-a[p]<x、a[i]-a[p-1]>x,为了方便计算采取了
求当选择p-1位置时多出来的天数为last然后在总贡献中减去last的贡献
ll last=low-a[p-1];
ans=max(ans,sum[i]-sum[p-1]-(1+last)*last/2);
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<" : "<<x<<endl;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
using namespace std;
const int maxn = 4e5 + 10;
ll a[maxn],sum[maxn];
void solve()
{
ll n,x;cin>>n>>x;
for(int i=1;i<=n;++i){
cin>>a[i];
a[i+n]=a[i];
sum[i]=sum[i+n]=(1+a[i])*a[i]/2;
}
for(int i=1;i<=2*n;++i){
a[i]+=a[i-1];
sum[i]+=sum[i-1];
}
ll ans=0,p,low;
for(int i=2*n;i>=1;--i){
if(a[i]<x) break;
low=a[i]-x;
p=lower_bound(a+1,a+1+2*n,low)-a;
if(a[i]-a[p]==x){
ans=max(ans,sum[i]-sum[p]);
}else{
ll last=low-a[p-1];
ans=max(ans,sum[i]-sum[p-1]-(1+last)*last/2);
}
}
cout<<ans<<endl;
}
int main()
{
// freopen("ii.txt","r",stdin);
// freopen("oo.txt","w",stdout);
solve();
}
参考博客:https://blog.csdn.net/weixin_45483201/article/details/106382451?fps=1