Typesetting math: 100%

Loading

题解 CF846C Four Segments

题意#

给定长度为n的序列a,求出三个点i,j,k(0<=i<=j<=k<=n),使得a[1]+...+a[i]-a[i+1]-...-a[j]+a[j+1]+...+a[k]-a[k+1]-...-a[n]最大

思路#

最开始没想出来,然后看了题解

先对序列求前缀和,设为sum

那么最大值为max{sumi(sumjsumi)+(sumksumj)(sumnsumk)}

化简后就是求max{sumi+sumksumj}i,j,k的位置

题解里面是枚举j,然后再O(n)扫前缀和求sumi,sumk的最大值

j是逐渐变化的,我们可以用单调队列来维护sumk的最大值,至于sumi的最大值直接维护即可

时间复杂度O(n)

代码#

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,ansi,ansj,ansk,l=1,r=0;
int a[5010],q[5010];
signed main(){
	long long ans=(-(1ll<<62));
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){scanf("%lld",&a[i]);a[i]+=a[i-1];}
	for(int i=1;i<=n;i++){
		while(l<=r && a[i]>a[q[r]])r--;
		q[++r]=i;
  }
	int ki=0,kk,sum1,sum2,sum3;
	for(int j=0;j<=n;j++){
		if(q[l]<j)l++;kk=q[l];
		if(a[ki]<a[j])ki=j;
		if(a[kk]+a[ki]-a[j]>ans)ans=a[kk]+a[ki]-a[j],ansi=ki,ansj=j,ansk=kk;
	}
	printf("%lld %lld %lld\n",ansi,ansj,ansk);
	return 0;
}
posted @   fpjo  阅读(109)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理
点击右上角即可分享
微信分享提示
主题色彩