昨晚的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;
}