//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#pragma comment(linxer, "/STACK:102400000,102400000")
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define ls i << 1
#define rs ls | 1
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define eps 1e-14
#define Pi acos(-1.0)
#define inf 0x3f3f3f3f
#define N 200010
#define M 200020
struct point{
LL x, y;
point(LL x = 0, LL y = 0) : x(x), y(y) {}
point operator - (const point &b) const {
return point(x - b.x, y - b.y);
}
LL operator * (const point &b) const {
return x * b.y - y * b.x;
}
};
LL tot, sum[N];
int a[N], q[N];
point p[N];
LL check(int i, int v){
return p[i].x * v + p[i].y;
}
int query(int L, int R, LL v){
while(L < R){
int m1 = (2 * L + R) / 3, m2 = (2 * R + L + 2) / 3;
if(check(q[m1], v) < check(q[m2], v))
L = m1 + 1;
else R = m2 - 1;
}
return q[L];
}
int main(){
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
sum[i] = sum[i-1] + a[i];
tot += 1LL * a[i] * i;
}
LL ans = tot;
int head = 0, tail = 0;
q[tail++] = n;
p[n] = point(n, -sum[n]);
for(int i = n - 1; i >= 1; --i){
int j = query(head, tail - 1, a[i]);
ans = max(ans, p[j].x * a[i] + p[j].y + tot + sum[i] - 1LL * a[i] * i);
p[i] = point(i, -sum[i]);
while(head + 1 < tail && (p[q[tail-1]] - p[q[tail-2]]) * (p[i] - p[q[tail-2]]) <= 0)
tail--;
q[tail++] = i;
}
head = tail = 0;
q[tail++] = 1;
p[1] = point(1, 0);
for(int i = 2; i <= n; ++i){
int j = query(head, tail - 1, a[i]);
ans = max(ans, p[j].x * a[i] + p[j].y + tot + sum[i-1] - 1LL * a[i] * i);
p[i] = point(i, -sum[i-1]);
while(head + 1 < tail && (p[q[tail-1]] - p[q[tail-2]]) * (p[i] - p[q[tail-2]]) >= 0)
tail--;
q[tail++] = i;
}
cout << ans << endl;
return 0;
}
Codeforces Round #344 (Div. 2) E - Product Sum (斜率dp)
最新推荐文章于 2021-09-10 20:04:52 发布