Codeforces Round #344 (Div. 2) E - Product Sum(三分 (java))

题意:n = 20w的数列, 价值val = sigma(i * Ai), 可以把任意一个数移到任意位置, 求价值最大值

思路:对每个数,分别左右移动, 三分求得移动的最佳位置


三分:

注意把要三分的区间向左向右各扩大一格,这样就不会使mid == midd出现了,避免了出错。

最后定出lb和ub的时候,要判断是否在合法区间外

代码:

import java.util.*;  
import java.math.*;  
import java.io.*;


public class Main {  
    public static void main(String[] args) { 
        InputStream inputStream = System.in;  
        OutputStream outputStream = System.out;  
        Scanner in = new Scanner(inputStream);  
        PrintWriter out = new PrintWriter(outputStream);  
        solve(in, out);  
        out.close();  
    }  
    
    static long []a;
    static long []val, f, b;
    
    
    static void solve(Scanner in, PrintWriter out) {  
    	int n = in.nextInt();
    	a = new long [n + 1];
    	val = new long [n + 1];
    	f = new long [n + 1];
    	b = new long [n + 1];
    	
    	for(int i = 1; i <= n; i ++)  a[i] = in.nextInt();

    	for(int i = 1; i <= n; i ++) val[i] = val[i - 1] + i * a[i];
    	for(int i = 1; i <= n; i ++) f[i] = f[i - 1] + (i - 1) * a[i];
    	for(int i = 1; i <= n; i ++) b[i] = b[i - 1] + (i + 1) * a[i];
    	long ans = val[n];
    	for(int i = 1; i <= n; i ++) {
    		int lb = Math.min(n, i + 1) - 1, ub = n + 1;
    		while(ub - lb > 1) {
    			int mid = (lb + ub) >> 1;
    			int midd = (mid + ub) >> 1;
    			long x = val[n] - val[mid] + val[i - 1] + mid * a[i] + (f[mid] - f[i]);
    			long y = val[n] - val[midd] + val[i - 1] + midd * a[i] + (f[midd] - f[i]);
    			if(x > y) ub = midd;
    			else lb = mid;
    		}
    		if(lb != Math.min(n, i + 1) - 1)
    			ans = Math.max(ans, val[n] - val[lb] + val[i - 1] + lb * a[i] + f[lb] - f[i]);
    		if(ub != n + 1)
    			ans = Math.max(ans, val[n] - val[ub] + val[i - 1] + ub * a[i] + f[ub] - f[i]);
    		lb = 0;
    		ub = Math.max(1, i - 1) + 1;
    		while(ub - lb > 1) {
    			int mid = (lb + ub) >> 1;
    			int midd = (mid + ub) >> 1;
    			long x = val[n] - val[i] + val[mid - 1] + mid * a[i] + b[i - 1] - b[mid - 1];
    			long y = val[n] - val[i] + val[midd - 1] + midd * a[i] + b[i - 1] - b[midd - 1];
    			if(x > y) ub = midd;
    			else lb = mid;
    		}
    		if(lb != 0)
    			ans = Math.max(ans,  val[n] - val[i] + val[lb - 1] + lb * a[i] + b[i - 1] - b[lb - 1]);
    		if(ub != Math.max(1,  i - 1) + 1)
    			ans = Math.max(ans, val[n] - val[i] + val[ub - 1] + ub * a[i] + b[i - 1] - b[ub - 1]); 
    	}
    	out.println(ans);
    	out.flush();
    }  
   
    

    static class Scanner {    
        BufferedReader br;    
        StringTokenizer st;    
                
        public Scanner(InputStream in) {  
            br = new BufferedReader(new InputStreamReader(in));  
            eat("");  
        }   
          
        private void eat(String s) {    
            st = new StringTokenizer(s);  
        }    
        
        public String nextLine() {    
            try {    
                return br.readLine();    
            } catch (IOException e) {    
                return null;    
            }    
        }    
        
        public boolean hasNext() {    
            while (!st.hasMoreTokens()) {    
                String s = nextLine();    
                if (s == null)    
                return false;    
                eat(s);    
            }    
            return true;    
        }    
        
        public String next() {    
            hasNext();    
            return st.nextToken();    
        }    
        
        public int nextInt() {    
            return Integer.parseInt(next());    
        }    
            
        public long nextLong() {    
            return Long.parseLong(next());    
        }    
                
        public double nextDouble() {    
            return Double.parseDouble(next());    
        }    
            
        public BigInteger nextBigInteger() {    
            return new BigInteger(next());    
        }    
            
    }    
}   




E. Product Sum
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Blake is the boss of Kris, however, this doesn't spoil their friendship. They often gather at the bar to talk about intriguing problems about maximising some values. This time the problem is really special.

You are given an array a of length n. The characteristic of this array is the value  — the sum of the products of the values aiby i. One may perform the following operation exactly once: pick some element of the array and move to any position. In particular, it's allowed to move the element to the beginning or to the end of the array. Also, it's allowed to put it back to the initial position. The goal is to get the array with the maximum possible value of characteristic.

Input

The first line of the input contains a single integer n (2 ≤ n ≤ 200 000) — the size of the array a.

The second line contains n integers ai (1 ≤ i ≤ n|ai| ≤ 1 000 000) — the elements of the array a.

Output

Print a single integer — the maximum possible value of characteristic of a that can be obtained by performing no more than one move.

Examples
input
4
4 3 2 5
output
39
input
5
1 1 2 7 1
output
49
input
3
1 1 2
output
9
Note

In the first sample, one may pick the first element and place it before the third (before 5). Thus, the answer will be3·1 + 2·2 + 4·3 + 5·4 = 39.

In the second sample, one may pick the fifth element of the array and place it before the third. The answer will be1·1 + 1·2 + 1·3 + 2·4 + 7·5 = 49.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值