AtCoder Beginner Contest 240 F

ABC 240

F

思路

维护前缀和B,以及B的前缀和C,然后在每次添加连续y个x的时候,从中找出最大的Ci(用pre记录),更新答案。
有四种情况
B0,x>0 那么新出现的Ci中的最大值就在最后一个元素
B0,x<0 新出现的ci中最大值即Ck,k=min(Bx,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 @   Liang2003  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示