AtCoder Beginner Contest 240 F
ABC 240
F
思路
维护前缀和B,以及B的前缀和C,然后在每次添加连续y个x的时候,从中找出最大的\(C_i\)(用pre记录),更新答案。
有四种情况
\(B\geq 0,x>0\) 那么新出现的\(C_i\)中的最大值就在最后一个元素
\(B\geq0,x<0\) 新出现的\(c_i\)中最大值即\(C_k,k=min(\frac {B}{-x},y)\)
\(B<0,x>0\) 如果画个图出来,C就是个开口向上的二次函数,两个端点取max
\(B<0,x<0\) 这个不用变,加了就变小不如不加
代码
void solve()
{
cin>>n>>m;
int b=0,c=0,ans=-1e18,pre=0;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
if(i==1)//特判一下,因为不知道怎么设初值
{
if(x>=0) ans=x*y*(y+1)/2;
else ans=x;
c+=b*y+(y+1)*y/2*x;
b+=x*y;
continue;
}
if(b>=0)
{
if(x>=0) pre =c+b*y+(y+1)*y/2*x;
else
{
int k=min(y,-b/x);
pre=c+b*k+(k+1)*k/2*x;
}
}
else pre=max(c,c+b*y+(y+1)*y/2*x);
ans=max(ans,pre);
c+=b*y+(y+1)*y/2*x;
b+=x*y;
}
cout<<ans<<endl;