2019 ICPC南昌邀请赛比赛 I. Max answer (单调栈+思维预处理)

Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values in the interval, multiplied by the smallest value in the interval.

Now she is planning to find the max value of the intervals in her array. Can you help her?

Input

First line contains an integer n(1 \le n \le 5 \times 10 ^5n(1≤n≤5×105).

Second line contains nn integers represent the array a (-10^5 \le a_i \le 10^5)a(−105≤ai​≤105).

Output

One line contains an integer represent the answer of the array.

样例输入复制

5
1 2 3 4 5

样例输出复制

36 

                大意就是让你获取区间和*区间最小值的最大是多少~

                网上有一个类似的题目一样的题意,不过在那上面数据只有正数没有负数,所以,在满足某个数为最小的数的时候,直接调取之前所处理好的限定区间(在这个区间里认定的ai是最小的,可以通过单调栈O(n)获得).但这里不同,存在负数就存在着很多需要考虑的问题,之前的处理好的区间也不再是正确的了~。

                这里的话,我们先从双边进行遍历,分别获得ai左边的(包括这个点)的能够获取的最大的区间和,和最右边的(包括这个点)能够获取的最大的区间和。然后同样处理获得ai左边的(包括这个点)的能够获取的最小的区间和,和最右边的(包括这个点)能够获取的最小的区间和,那么我们就可以知道包含点ai的最大的区间和 和最小的区间和是多少了~~。这样的话,ai*(最大的区间和)和ai*(最小的区间和)其中一个肯定是以为ai最小点能够获得的最大的所求值。

                奥,补充一下,我们所获取的最大的区间和和最小的区间和可能超过了我们之前处理的限定区间,在这种情况下我们别忘了进行相减。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
long long m[maxn];
long long sum[maxn], l[maxn], r[maxn];
long long zsum[maxn], zzsum[maxn];
long long fsum[maxn], ffsum[maxn];
int main() {
	ios::sync_with_stdio(0);
	int n;
	cin >> n;
	sum[0] = 0; 
	for (int i = 1; i <= n; i++) {
		cin >> m[i]; sum[i] = sum[i - 1] + m[i];
		l[i] = r[i] = i;
	}sum[n + 1] = sum[n];
	stack<int> s;
	int i = 1;
	while (i<=n) {
		if (s.empty() || m[i] > m[s.top()]) {
			s.push(i);
			++i;
		}
		else {
			l[i] = l[s.top()];
			s.pop();
		}
	}
	while (!s.empty())
		s.pop();
	i = n;
	while (i >= 1) {
		if (s.empty() || m[i] > m[s.top()]) {
			s.push(i);
			--i;
		}
		else {
			r[i] = r[s.top()];
			s.pop();
		}
	}


	long long su = 0, t = 0;
	for (int i = 1; i <= n; i++) {
		su += m[i];
		zsum[i] = su;
		if (t < l[i]) {
			zsum[i] -= sum[l[i] - 1] - sum[t];
		}
		if (su < 0) {
			su = 0;
			t = i;
		}
	}
	su = 0; t = n + 1;
	for (int i = n; i >= 1; i--) {
		su += m[i];
		zzsum[i] = su;
		if (t > r[i]) {
			zzsum[i] -= sum[t - 1] - sum[r[i]];
		}
		if (su < 0) {
			su = 0;
			t = i;
		}
	}
	// 负数开始。
	su = 0; t = 0;
	for (int i = 1; i <= n; i++) {
		su += m[i];
		fsum[i] = su;
	//	cout << su << " "<<t<<" "<<l[i]<<endl;
		if (t < l[i]) {
		//	cout << i <<" now: "<<sum[l[i]-1]<<" "<<sum[t]<< endl;
			fsum[i] -= sum[l[i] - 1] - sum[t];
		}
		if (su > 0) {
			su = 0;
			t = i;
		}
	}
	su = 0; t = n;
	for (int i = n; i >= 1; i--) {
		su += m[i];
		ffsum[i] = su;
		if (t > r[i]) {
			ffsum[i] -= sum[t - 1] - sum[r[i]];
		}
		if (su > 0) {
			su = 0;
			t = i;
		}
	}
	long long ans = -0x3f3f3f3f3f3f3f3f;
	for (int i = 1; i <= n; i++) {
		long long a = zsum[i] - m[i] + zzsum[i];
		long long b = fsum[i] - m[i] + ffsum[i];
		ans = max(m[i] * a, ans);
		ans = max(ans, m[i] * b);
	}
	cout << ans << "\n";
	return 0;
}

 

 

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
14085次浏览 132人参与
# AI面会问哪些问题? #
845次浏览 21人参与
# MiniMax求职进展汇总 #
24691次浏览 317人参与
# 你的实习产出是真实的还是包装的? #
2497次浏览 48人参与
# AI时代,哪个岗位还有“活路” #
2565次浏览 49人参与
# 长得好看会提高面试通过率吗? #
2687次浏览 41人参与
# 巨人网络春招 #
11471次浏览 224人参与
# 你做过最难的笔试是哪家公司 #
1039次浏览 18人参与
# HR最不可信的一句话是__ #
959次浏览 31人参与
# 沪漂/北漂你觉得哪个更苦? #
990次浏览 29人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7921次浏览 43人参与
# XX请雇我工作 #
51131次浏览 171人参与
# 简历中的项目经历要怎么写? #
310803次浏览 4252人参与
# 简历第一个项目做什么 #
32008次浏览 354人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152752次浏览 888人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187504次浏览 1123人参与
# AI时代,哪些岗位最容易被淘汰 #
64444次浏览 860人参与
# 如果重来一次你还会读研吗 #
229954次浏览 2011人参与
# 正在春招的你,也参与了去年秋招吗? #
364069次浏览 2640人参与
# 腾讯音乐求职进展汇总 #
160800次浏览 1114人参与
# 你怎么看待AI面试 #
180570次浏览 1291人参与
# 投格力的你,拿到offer了吗? #
178092次浏览 889人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务