#斜率优化,二分#CF631E Product Sum
题目
有一个数列 \(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]\)
综上所述,转化为两个式子:
\]
以下式为例,若 \(\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的更多相关文章
- BZOJ_2726_[SDOI2012]任务安排_斜率优化+二分
BZOJ_2726_[SDOI2012]任务安排_斜率优化+二分 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这 ...
- [SDOI2012]任务安排 BZOJ2726 斜率优化+二分查找
网上的题解...状态就没有一个和我一样的...这让我有些无从下手... 分析: 我们考虑,正常的斜率优化满足x(i)单调递增,k(i)单调递增,那么我们就可以只用维护一个单调队列满足对于当前的x(i) ...
- P3994 高速公路 树形DP+斜率优化+二分
$ \color{#0066ff}{ 题目描述 }$ C国拥有一张四通八达的高速公路网树,其中有n个城市,城市之间由一共n-1条高速公路连接.除了首都1号城市,每个城市都有一家本地的客运公司,可以发车 ...
- BZOJ2726:任务安排(DP+斜率优化+二分)
机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务 ...
- 小A与最大子段和 斜率优化 + 二分 + 细节
Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) ...
- 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 ...
- 洛谷P3648 [APIO2014]序列分割(斜率优化)
传送门 没想到这种多个状态转移的还能用上斜率优化……学到了…… 首先我们可以发现,切的顺序对最终答案是没有影响的 比方说有一个序列$abc$,每一个字母都代表几个数字,那么先切$ab$再切$bc$,得 ...
- BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化
BZOJ_3672_ [Noi2014]购票_CDQ分治+斜率优化 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参 ...
- 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 ...
- Codeforces 631E Product Sum 斜率优化
我们先把问题分成两部分, 一部分是把元素往前移, 另一部分是把元素往后移.对于一个 i 后的一个位置, 我们考虑前面哪个移到这里来最优. 我们设最优值为val, val = max(a[ j ] ...
随机推荐
- E4X已经被废弃,各浏览器基本上不再支持它;
E4X是一种在ECMAScript标准的基础上加入的动态XML支持的程序语言扩展. 到2019年,目前主流浏览器已经不太支持它了,一些版本的Firefox浏览器或许还可以使用,但它已经在主流浏览器的主 ...
- 文心一言 VS 讯飞星火 VS chatgpt (203)-- 算法导论15.3 2题
二.对一个16个元素的数组,画出2.3.1节中MERGE-SORT过程运行的递归调用树.解释备忘技术为什么对MERGE-SORT这种分治算法无效.需要写代码的时候,请用go语言. 文心一言,代码不完整 ...
- instance must be started before calling this method
解决方法 检查zk的连接数: 端口号: 数据库连接配置: zk的连接配置: 如果都没有问题,就重启容器.
- 【LeetCode字符串#extra】KMP巩固练习:旋转字符串、字符串轮转
旋转字符串 https://leetcode.cn/problems/rotate-string/ 给定两个字符串, s 和 goal.如果在若干次旋转操作之后,s 能变成 goal ,那么返回 tr ...
- vscode 利用正则 搜索标签 tags (?=.*关键字1)(?=.*关键字2).*
vscode 利用正则 搜索标签 (?=.关键字1)(?=.关键字2).* 这里关键词是可以多个并且不按照顺序搜索的,就是写起来需要 (?=.关键字) 最后. 结尾 我是不是需要制作一个转换的小工具呢 ...
- 2023山东省“技能兴鲁”职业技能大赛-学生组初赛wp
PWN pwn1 c++ pwn,cin 直接相当于 gets 了,程序有后门,保护基本没开,在 change 的最后一个输入点改掉返回地址为后门地址即可 from pwn import * cont ...
- j-link仿真器的作用和价值以及Ubuntu下使用注意事项
一 J-LINK是什么? J-Link是SEGGER公司为支持仿真ARM内核芯片推出的JTAG仿真器.配合IAR EWAR,ADS,KEIL,WINARM,RealView等集成开发环境支持所有A ...
- MAKEFILE的学习
Makefile/cmake/configure 重点学习Cmake 首先是简单的MakeFile入门 1.1 简单Makefile 范例1.1 all: @echo "Hello all& ...
- day03-功能实现03
功能实现03 9.功能08-分页显示 9.1需求分析 将查询的数据进行分页显示,要求功能如下: 显示共多少条记录 可以设置每页显示几条 点击第几页,显示对应的数据 9.2思路分析 后端使用MyBati ...
- Java递归实现全排列改进(一)---利用HashSet实现去重
import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iter ...