思路:尺取+贪心
请看注释!
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ll long long
#define endl "\n"
using namespace std;
const int N = 4e5+5;
ll d[N]={0}, dd[N]={0};
int main()
{
ll n, x;
scanf("%lld %lld",&n,&x);
for(ll i=1;i<=n;++i)
{
scanf("%lld",&d[i]);//该月份的天数
dd[i] = d[i]*(1ll+d[i])/2ll;//某一月份全取的次数
}
for(int i=1;i<=n;++i)//对出现下一年的情况进行预处理
{
d[n+i] = d[i];
dd[n+i] = dd[i];
}
ll now = 0, now1 = 0;
int l = n+1, r = n+1;
while(now<=x&&l>=2)//向前进行尺取,看看会到哪
{
if(now+d[l]<=x)//仍旧可以取走一整月
{
now += d[l];//已消耗天数增加
now1 += dd[l];//已获得 hug数增加
--l;//考虑再前面一个月份
}
else
{
break;//退出循环,已经不能再取走一整月
}
}
ll re = x - now;//残余的空闲时间
ll mx = now1+(d[l]+d[l]-re+1)*re/2;//计算总共有多少hug
//为之前获得的所有hug加上剩余天数取得的hug
while(r<n+n)//向后进行尺取
{
now += d[++r];//天数增加
now1 += dd[r];//拥抱增加
while(now>x)//当已消耗天数超出预期
{
now -= d[++l];//消除最前面一月的影响
now1 -= dd[l];
}
ll re = x - now;
mx = max(mx,now1+(d[l]+d[l]-re+1)*re/2);//更新答案
}
cout << mx << endl;
return 0;
}