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;
	
posted @ 2023-03-14 19:27  Liang2003  阅读(17)  评论(0编辑  收藏  举报