3.22 GESP6 T2

环线
小A喜欢乘坐地铁!
地铁环线一共有n个站点(n<3*10^5)。 每个站点有一个快乐值A[i]。每当经过该站台,小A就能得到该站台的快乐值。注意,快乐值可能为负数(|a[i]|<=10^9)。
注意:第i站的下一站为第i+1站,但第n站的下一站为第1站。
每个站点小A最多经过一次。求他得到的最大快乐值之和。

样例1

 4
 -1 2 3 0
 5

(解释:第2站-第3站)
样例2

 5
 -3 4 -5 1 3
 5

(解释:只有第3站不坐)

思路
ONE 暴力
n^2的复杂度。

TWO 区间和
通过观察可以发现,从一个点L到点R(L<R)分两种情况:
路径1:L->1->R
路径2:l->R
当然,在这个基础上,我们能得到:
第一种的数值之和=全程的数值之和-第二种的数值之和。
因此,这道题,可以转化成区间和问题!

但是时间复杂度不会有丝毫优化。
……

TWO pro
通过TWO不难发现,对于一个路径2,若它有固定的R,那么让其1->L的和最小,就能做到数值之和最大。
sum=前缀和[R]-min(前缀和1-R)
同样的原理,要使一个有固定R的路径1和最大,那就要让1->L的和最大。
sum2=前缀和[n]-[前缀和[R]-max(前缀和[1-R])]
然后再把sum与sum2录入答案就可以了。
O(n),考场AC.

代码

点击查看代码
/*CPP*/
#include <bits/stdc++.h>
using namespace std;
long long a[300005],b[300005];
long long maxn[300005],minx[300005];//maxn[i]=max(b[1],b[2],b[3]...b[i]),minx同理 
long long n,ans;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=b[i-1]+a[i];
		maxn[i]=max(maxn[i-1],b[i]);//注意,是B i而不是A i 
		minx[i]=min(minx[i-1],b[i]);
	}
	for(int i=1;i<=n;i++){
		long long sum,sum2; 
		sum=b[i]-minx[i];//L-R 
		sum2=b[n]-b[i]+maxn[i];//L-1-R 
		ans=max(ans,max(sum,sum2));
	}cout<<ans;
	
	return 0;
}
posted @ 2025-03-22 21:26  虚拟星辰  阅读(7)  评论(0)    收藏  举报