[codeforces631E]Product Sum
1 second
256 megabytes
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 valuesai by 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.

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.
Print a single integer — the maximum possible value of characteristic of a that can be obtained by performing no more than one move.
4
4 3 2 5
39
5
1 1 2 7 1
49
3
1 1 2
9
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.
题解:
刚看这个题我十分的懵逼,这怎么做?
于是我就想了个暴力O(n2)的算法:如果没有这个"exactly once"的移动,问题的答案很容易算出来,设为ans
而由于只能移动一次,所以我可以枚举移动的方案,看每种移动对答案的贡献,设为delta,选最大贡献,最终答案为ans+delta
scanf("%d",&n);
for(LL i=;i<=n;i++)
{
cin>>a[i];
s[i]=a[i]+s[i-];
ans1+=a[i]*i;
}
for(int l=;l<=n;l++)
for(int r=l+;r<=n;r++)
{
delta=max(delta,a[l]*(r-l)-(s[r]-s[l]));
delta=max(delta,s[r-]-s[l-]-a[r]*(r-l));
}
cout<<delta+ans1;
一个简单的暴力
这样肯定会t,所以我们考虑一下刚才那个暴力的式子
"delta=max(delta,a[l]*(r-l)-(s[r]-s[l]));"
"delta=max(delta,s[r-1]-s[l-1]-a[r]*(r-l));"
把这两个式子变形,可以得到:
a[l]*(r-l)-(s[r]-s[l])=a[l]*r-a[l]*l-s[r]+s[l]=(a[l]*r-s[r])+(s[l]-a[l]*l)
s[r-1]-s[l-1]-a[r]*(r-l)=a[r]*l-a[r]*r+s[r-1]-s[l-1]=(a[r]*l-s[l-1])+(s[r-1]-a[r]*r)
对于每一个l/r,右面括号里的项都是确定的,现在需要的就是确定左面括号中的最大值
而左面括号的式子形如一个k*x+b的一次函数,所以不难想到维护一个下凸壳,对于每个a[i]在下凸壳中查找
不过,这个式子并没有决策单调性,所以我们不能用单调队列维护,而是一直保存着那个下凸壳,每次用log(n)二分查找
这样就可以解决这个问题了,最后答案依然是ans+delta
代码见下:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const int N=;
int n;
inline LL max(LL a,LL b){return a>b?a:b;}
LL a[N],s[N],ans1,delta=;
struct node{LL a,b;};
inline LL f(LL a,node b){return b.a*a+b.b;}
node q[N];int h,t;
inline LL query(LL x)
{
int le=,ri=t;
while(ri-le>)
{
int mi=(le+ri)>>;
if(f(x,q[mi])<=f(x,q[mi+]))
le=mi;
else ri=mi;
}
return f(x,q[ri]);
}
int main()
{
scanf("%d",&n);
for(LL i=;i<=n;i++)
{
cin>>a[i];
s[i]=a[i]+s[i-];
ans1+=a[i]*i;
}
t=;
for(LL r=;r<=n;r++)
{
node tmp=(node){r-,-s[r-]};
while(t>&&(q[t].b-tmp.b)*(q[t].a-q[t-].a)<=(q[t-].b-q[t].b)*(tmp.a-q[t].a))t--;
q[++t]=tmp;
delta=max(delta,query(a[r])-a[r]*r+s[r-]);
}
t=;
for(LL l=n-;l>=;l--)
{
node tmp=(node){-(l+),-s[l+]};
while(t>&&(q[t].b-tmp.b)*(q[t].a-q[t-].a)<=(q[t-].b-q[t].b)*(tmp.a-q[t].a))t--;
q[++t]=tmp;
delta=max(delta,query(-a[l])-a[l]*l+s[l]);
}
cout<<delta+ans1;
}
codeforces631E
[codeforces631E]Product Sum的更多相关文章
- Codeforces Round #344 (Div. 2) E. Product Sum 维护凸壳
E. Product Sum 题目连接: http://www.codeforces.com/contest/631/problem/E Description Blake is the boss o ...
- 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 ] ...
- CS Academy Sliding Product Sum(组合数)
题意 有一个长为 \(N\) 的序列 \(A = [1, 2, 3, \dots, N]\) ,求所有长度 \(\le K\) 的子串权值积的和,对于 \(M\) 取模. \(N \le 10^{18 ...
- @codeforces - 631E@ Product Sum
目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 给定一个序列 a,定义它的权值 \(c = \sum_{i=1}^{ ...
- Subarray Product Less Than K LT713
Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...
- 数据库sql语句规则
sql练习: 创建一个名称为mydb1的数据库. create database mydb1; 查看库 show databases; 创建一个使用utf-8字符集的mydb2数据库. create ...
- MySQL高级查询 之 与 Group By 一起使用的函数 和 关键字
1 GROUP_CONCAT mysql> SELECT student_name, -> GROUP_CONCAT(test_score) -> FROM stud ...
- HANA SQL
约束 注释 你可以给你的 SQL 语句添加注释来增加可读性和可维护性. SQL 语句中注释的分隔如下: l 双连字符“--”.所有在双连字符之后直到行尾的内容都被 SQL 解析器认为是注释. l ...
随机推荐
- 2017/4/25-SAX解析XML文件
SAX解析XML 1.分析 SAX是按照XML文件的顺序执行,可以说是边扫描,边解析.所以无须将整个文件加载至内存中. 2.优点 1)占用内存少. 2)解析效率高. 3.缺点 1)只能进行读取. 2) ...
- Java中的集合与线程的Demo
一.简单线程同步问题 package com.ietree.multithread.sync; import java.util.Vector; public class Tickets { publ ...
- Omi树组件omi-tree编写指南
Omi框架能够以少量的代码声明式地编写可拖拽移动节点的树形组件. 通常树组件能够考验UI框架的健壮性,因为需要使用到UI框架的如下特性: 组件嵌套 组件传值 组件批量传值 组件依赖自身递归嵌套(nes ...
- 01背包Bone Collector
好几天没写博客了,整天忙着打比赛,希望能有参加省赛的资格,不容易啊. 今天复习背包,之前集训讲过,现在又忘了,昨天杭电校赛刚好有一题背包,居然不会做了,好尴尬,重新复习一下. https://vjud ...
- 微信小程序(组件demo)以及预览方法:(小程序交流群:604788754)
1. 获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的"设置"-"开发者设置"中,查看到微信小程序的 Ap ...
- 【NLP】3000篇搜狐新闻语料数据预处理器的python实现
3000篇搜狐新闻语料数据预处理器的python实现 白宁超 2017年5月5日17:20:04 摘要: 关于自然语言处理模型训练亦或是数据挖掘.文本处理等等,均离不开数据清洗,数据预处理的工作.这里 ...
- OC分类(Category)
Category 分类 ,又称为类别.类目 概念 Category有多种翻译:分类.类别.类目(一般叫分类的多) Category式OC特有的语法,其他语言没有的语法(类似于C#语言中的"扩 ...
- JS-监听文本回车事件写入数据表单
场景 ERP系统扫描输入货品编号到文本框后,触发写入记录到数据表格,并对数据进行渲染. 解决方案 通过发现回车或者换行符,则写入数据表格 代码 //监听文本框输入事件 $('#gidinp ...
- 【less和sass的区别,你了解多少?】
在介绍less和sass的区别之前,我们先来了解一下他们的定义: 一.Less.Sass/Scss是什么? 1.Less: 是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量.继承.运算.函数 ...
- 将C-风格字符串用作string对象引用参数
string类定义了一种char*到string的转换功能,这使得可以使用C-风格字符串来初始化string对象. 类型为const引用的形参其中一个属性表明:假设实参的参数类型与引用参数不匹配,但可 ...