题目

有一个数列 \(a\),其权值为 \(\sum_{i=1}^ni*a_i\),

现在可以任意选择其中一个数字扔到任意位置,使权值和最大。

\(n\leq 2*10^5,|a_i|\leq 10^6\)


分析

不妨先将原数列的权值算一遍,那么其实只是让改变的权值尽量大。

设选择的数字为 \(a_i\),选择的位置为 \(j\)。

当 \(j<i\) 时,表示将这个数放在第 \(j\) 个位置,同时 \([j,i)\) 的数往后移。

改变的权值就是 \(s_{i-1}-a_i*i+a_i*j-s_{j-1},j\in [1,i)\)

令 \(j'=j-1,i'=i-1\) 也就是求 \(s_{i'}-a_{i'+1}*i'+a_{i'+1}*j'-s_{j'}\)

当 \(j>i\) 时,表示将这个数放在第 \(j\) 个位置,同时 \((i,j]\) 的数往前移。

改变的权值就是 \(s_i-a_i*i+a_i*j-s_j,j\in (i,n]\)

综上所述,转化为两个式子:

\[\begin{align}\max_{0\leq j<i<n} s_i-a_{i+1}*i+a_{i+1}*j-s_j\\\max_{1\leq i<j\leq n} s_i-a_i*i+a_i*j-s_j\end{align}
\]

以下式为例,若 \(\exists k>j,a_i*k-s_k\geq a_i*j-s_j\),即 \(\frac{s_k-s_j}{k-j}\leq a_i\) 时,将 \(j\) 弹出。

考虑到求的是最大值,那么维护一个上凸壳,理应是斜率单调递减,不过由于倒序实际上具体维护时是单调递增的。

因为 \(a_i\) 不具有单调性,所以在凸壳上面二分即可。


代码

#include <cstdio>
#include <cctype>
#define fz(j,i) (s[i]-s[j])
#define fm(j,i) (i-j)
using namespace std;
const int N=200011; typedef long long lll;
lll a[N],s[N],sum,ans; int q[N],n,head,tail;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
lll max(lll a,lll b){return a>b?a:b;}
int lower(lll x){
int l=head,r=tail;
while (l<r){
int mid=(l+r+1)>>1;
if (fz(q[mid-1],q[mid])<=x*fm(q[mid-1],q[mid])) l=mid;
else r=mid-1;
}
return q[l];
}
int upper(lll x){
int l=head,r=tail;
while (l<r){
int mid=(l+r)>>1;
if (fz(q[mid],q[mid+1])>=x*fm(q[mid],q[mid+1])) r=mid;
else l=mid+1;
}
return q[l];
}
int main(){
n=iut();
for (int i=1;i<=n;++i){
a[i]=iut(),s[i]=s[i-1]+a[i];
sum+=a[i]*i;
}
head=tail=1;
for (int i=1;i<n;++i){
int now=lower(a[i+1]); ans=max(ans,s[i]+(now-i)*a[i+1]-s[now]);
ans=max(ans,s[i]+(q[tail]-i)*a[i+1]-s[q[tail]]);
while (head<tail&&fz(q[tail-1],q[tail])*fm(q[tail],i)>=fz(q[tail],i)*fm(q[tail-1],q[tail])) --tail;
q[++tail]=i;
}
head=tail=1,q[1]=n;
for (int i=n-1;i;--i){
int now=upper(a[i]); ans=max(ans,s[i]+(now-i)*a[i]-s[now]);
while (head<tail&&fz(q[tail-1],q[tail])*fm(q[tail],i)<=fz(q[tail],i)*fm(q[tail-1],q[tail])) --tail;
q[++tail]=i;
}
return !printf("%lld",ans+sum);
}

#斜率优化,二分#CF631E Product Sum的更多相关文章

  1. BZOJ_2726_[SDOI2012]任务安排_斜率优化+二分

    BZOJ_2726_[SDOI2012]任务安排_斜率优化+二分 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这 ...

  2. [SDOI2012]任务安排 BZOJ2726 斜率优化+二分查找

    网上的题解...状态就没有一个和我一样的...这让我有些无从下手... 分析: 我们考虑,正常的斜率优化满足x(i)单调递增,k(i)单调递增,那么我们就可以只用维护一个单调队列满足对于当前的x(i) ...

  3. P3994 高速公路 树形DP+斜率优化+二分

    $ \color{#0066ff}{ 题目描述 }$ C国拥有一张四通八达的高速公路网树,其中有n个城市,城市之间由一共n-1条高速公路连接.除了首都1号城市,每个城市都有一家本地的客运公司,可以发车 ...

  4. BZOJ2726:任务安排(DP+斜率优化+二分)

    机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务 ...

  5. 小A与最大子段和 斜率优化 + 二分 + 细节

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...

  6. CodeForces - 660F:Bear and Bowling 4(DP+斜率优化)

    Limak is an old brown bear. He often goes bowling with his friends. Today he feels really good and t ...

  7. 洛谷P3648 [APIO2014]序列分割(斜率优化)

    传送门 没想到这种多个状态转移的还能用上斜率优化……学到了…… 首先我们可以发现,切的顺序对最终答案是没有影响的 比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得 ...

  8. BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化

    BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...

  9. Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP

    E. Product Sum   Blake is the boss of Kris, however, this doesn't spoil their friendship. They often ...

  10. Codeforces 631E Product Sum 斜率优化

    我们先把问题分成两部分, 一部分是把元素往前移, 另一部分是把元素往后移.对于一个 i 后的一个位置, 我们考虑前面哪个移到这里来最优. 我们设最优值为val,   val = max(a[ j ] ...

随机推荐

  1. Redis能保证数据不丢失吗?

    大家即使没用过Redis,也应该都听说过Redis的威名. Redis是一种Nosql类型的数据存储,全称Remote Dictionary Server,也就是远程字典服务器,用过Dictionar ...

  2. select_for_update悲观锁

    例子,银行存款和撤销方法 1.用户A提取帐户 - 余额为100 $. 2.用户B提取帐户 - 余额为100 $. 3.用户B退出30 $ - 余额更新为100 $ - 30 $ = 70 $. 4.用 ...

  3. JVM运行时参数

    JVM运行时参数 JVM运行时参数是用于配置和调整Java虚拟机的行为和性能的参数.这些参数可以在启动Java应用程序时通过命令行或配置文件进行设置,合理配置参数可以使JVM虚拟机的达到更好的性能,降 ...

  4. 《Similarity-based Memory Enhanced Joint Entity and Relation Extraction》论文阅读笔记

    代码 原文 摘要 文档级联合实体和关系抽取是一项难度很大的信息抽取任务,它要求用一个神经网络同时完成四个子任务,分别是:提及检测.共指消解.实体分类和关系抽取.目前的方法大多采用顺序的多任务学习方式, ...

  5. 【Azure 应用服务】Azure Function App Linux环境下的Python Function,安装 psycopg2 模块错误

    问题描述 在Azure中创建Function App(函数应用), 用以运行Python代码(Python Version 3.7). 通过VS Code创建一个HttpTrigger的Functio ...

  6. [Python] 协程学习过程

    开始 ​ 之前一直在做那个rProxy的项目,后来发现,服务端不用协程或者异步编程这样的手段是不行的,最主要的问题就是对于每个http请求都对应一个线程,这个开销非常大.对于一个网页而言,四五十个ht ...

  7. Dreamweaver基础教程:学习CSS

    目录 CSS 简介 CSS 语法 Id 和 Class id 选择器 class 选择器 CSS 创建 外部样式表 内部样式表 内联样式 多重样式 多重样式优先级 背景(background) 背景颜 ...

  8. glibc 2.23 源码分析

    1. 基础知识 1.1 Linux 进程内存布局 Linux 系统在装载 elf 格式的程序文件时,会调用 loader 把可执行文件中的各个段依次载入到从某一地址开始的空间中(载入地址取决于 lin ...

  9. github无法访问?vscode 无法使用github登录同步? 改 hosts 吧

    一.无法访问 github.com ? 想要去 github.com 上拿来主义,结果访问不了,或者 npm 时一直失败? 是什么原因不用问,直接使用 https://tool.lu/ip/  查询到 ...

  10. 后端基础PHP—正则表达

    后端基础PHP-正则表达式 1.正则表达式的介绍 2.正则表达式的语法 一.正则表达式的介绍 正则表达式的介绍 · 正则表达式,又称规则表达式,通过一种特殊的语言来挑选符合条件的数据 · 在代码中简写 ...