I. Max answer(ICPC南昌邀请赛 I题目)

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值