The Preliminary Contest for ICPC China Nanchang National Invitational and International Silk-Road Programming Contest.
一开始想着线段树,用线段树搞了半天,一拍脑瓜,发现自己白费功夫被自己蠢到了哈哈哈
后来想到对每一个数都找一个合适的区间,再求和相乘就能得到包括这个元素的区间最大值
废话不多说,直接上AC代码吧 (赛后发现代码有很多可以改进的地方,有时间的时候再写吧^ ^)
/*
* Copyright (c) 2019 Ng Kimbing, HNU, All rights reserved. May not be used, modified, or copied without permission.
* @Author: Ng Kimbing, HNU.
* @LastModified:2019-04-20 T 12:12:19.755 +08:00
*/
package ACMProblems.ICPC;
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
static BufferedReader reader;
static StringTokenizer tokenizer;
public static void setStream(InputStream input) {
reader = new BufferedReader(
new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
public static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(
reader.readLine());
}
return tokenizer.nextToken();
}
public static String readLine() throws IOException {
return reader.readLine();
}
public static int nextInt() throws IOException {
return Integer.parseInt(next());
}
public static char nextChar() throws IOException {
return next().charAt(0);
}
public static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
static int maxN = 500005;
static long[] arr = new long[maxN];
static long[] sum = new long[maxN];
static int[] left = new int[maxN];
static int[] right = new int[maxN];
static int[] left2 = new int[maxN];
static int[] right2 = new int[maxN];
static long infinite = 0x3f3f3f3f3f3f3f3fL;
/*
5
-1 -2 -10 6 7
*/
static int n;
static long getIndex(int id, boolean positive) {
if (id == 0 || id == n + 1)
// if (positive)
return -0x3f3f3f3f3f3f3f3fL;
// else return 0x3f3f3f3f3f3f3f3fL;
else return arr[id];
}
public static void main(String[] args) throws Exception {
setStream(System.in);
n = nextInt();
for (int i = 1; i <= n; i++) {
arr[i] = nextInt();
sum[i] = sum[i - 1] + arr[i]; //前缀和
right2[i] = left2[i] = left[i] = right[i] = i;
}
arr[0] = arr[n + 1] = -0x3f3f3f3f3f3f3f3fL;
for (int i = 1; i <= n; i++) {
if (arr[i] >= 0)
while (arr[i] <= arr[left[i] - 1])
left[i] = left[left[i] - 1];
else {
int temp = left2[i] - 1;
while (true) {
if (temp < 0)
break;
if (temp != 0 && arr[i] > arr[temp])
break;
if ((sum[i] - sum[temp]) < (sum[i] - sum[left2[i] - 1])) {
left2[i] = temp + 1;
}
--temp;
}
}
}
for (int i = n; i >= 1; i--) {
if (arr[i] >= 0)
while (arr[i] <= arr[right[i] + 1])
right[i] = right[right[i] + 1];
else {
int temp = right2[i] + 1;
while (true) {
if (temp < 0)
break;
if (temp != 0 && arr[i] > arr[temp])
break;
if ((sum[temp] - sum[left2[i] - 1]) < (sum[right2[i]] - sum[left2[i] - 1])) {
right2[i] = temp;
}
++temp;
}
}
}
long result = -1;
for (int i = 1; i <= n; i++) {
long temp = arr[i] * (sum[right[i]] - sum[left[i] - 1]);
long temp2 = arr[i] * (sum[right2[i]] - sum[left2[i] - 1]);
temp = Math.max(temp, temp2);
if (result < temp)
result = temp;
}
out.println(result);
out.flush();
}
}
//5
// -1 2 3 -6 -10