zoukankan      html  css  js  c++  java
  • CodeForces 631E Product Sum

    Description

    给一个长度为 (n) 的序列,任意移动一个数,使得 (sum a[i] imes i) 最大。

    (2le nle 2 imes 10^5,left|a[i] ight|le 10^6)

    Solution

    考虑不移动时答案为 (ans) ,进行一次移动后答案为 (ans')

    考虑固定 (x) ,枚举从 (x) 移动向 (y(yge x))(y<x) 时同理):

    [ans' = ans + a[x] imes y - a[x] imes x - (sum[y] - sum[x]) ]

    整理一下

    [ans'=ans+(sum[x] - a[x] imes x) + (a[x] imes y - sum[y]) ]

    把与 (x) 相关的看为常数,定义

    [f(y)=a[x] imes y - sum[y] ]

    这玩意儿是凸的,所以可以三分最高点了。

    #include<bits/stdc++.h>
    using namespace std;
    
    template <class T> inline void read(T &x) {
    	x = 0; bool flag = 0; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == 45) flag = 1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48; if (flag) x = -x;
    }
    
    #define N 200010
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define ll long long
    
    int n;
    ll a[N], sum[N], tot;
    
    inline ll calc(int x, int y) {
    	if (x <= y) return tot + a[x] * (y - x) - (sum[y] - sum[x]);
    	return tot + a[x] * (y - x) + (sum[x - 1] - sum[y - 1]);
    }
    
    int main() {
    	read(n);
    	rep(i, 1, n) read(a[i]), sum[i] = sum[i - 1] + a[i], tot += i * a[i];
    	ll ans = -(1ll << 62);
    	rep(i, 1, n) {
    		int l = 1, r = n;
    		ll cur = -(1ll << 62);
    		while (l <= r) {
    			int mid1 = l + (r - l) / 3, mid2 = r - (r - l) / 3;
    			ll ans1 = calc(i, mid1), ans2 = calc(i, mid2);
    			if (ans1 > ans2) r = mid2 - 1, cur = max(cur, ans1);
    			else l = mid1 + 1, cur = max(cur, ans2);
    		}
    		ans = max(ans, cur);
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    操作系统
    redis
    数据库原理与mysql
    计算机网络
    重写、重载、隐藏以及多态分析
    c++复习重点
    重装系统记录
    正则表达式匹配ip地址
    信号量和互斥锁的区别 互斥量与临界区的区别
    为Markdown文件生成目录
  • 原文地址:https://www.cnblogs.com/aziint/p/9366898.html
Copyright © 2011-2022 走看看