codeforces 631E Product Sum (dp凸单调性)

来源:互联网 发布:java log输出 到网页 编辑:程序博客网 时间:2024/05/29 01:55
<a target=_blank href="http://codeforces.com/problemset/problem/631/E" style="color: rgb(0, 0, 204); margin-top: 0px; font-family: verdana, arial, sans-serif; font-size: 13px; text-align: center;">Product Sum</a>
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<stdio.h>#include<algorithm>#include<cmath>#include<map>#include<queue>#include<bitset>#include<stack>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")#define inf 0x3f3f3f3f#define eps 1e-9#define pii pair<int,int>#define MP make_pair#define LL  long long#define ULL unsigned long long #define N ( 1000000 + 10 )#define M ( 200000 + 10)#define mod  1000000007/*i < j$ans[i][j] = {(i, j-1) | a[i] * (i+1)} + a[j] * i - ( {(i,j-1) | a[i] * i} + a[j] * j);            = a[j] * (i-j) + sum[i][j-1]            = a[j] * i - a[j]*j + s[j-1] - s[i-1];            = a[j] * i - s[i-1] + s[j-1] - a[j]*j; // f[j] = s[j-1] - a[j] * j            = a[j] * i - s[i-1] + f[j]; // g[i]            i1 < i2            a[j] * i1 - s[i1-1] < a[j] * i2 - s[i2-1]            (s[i2-1] - s[i1-1])/(i2-i1) > a[j] // ll(i1, i2)            i1 < i2 < ill(i1, i2) >= ll(i2, i)(s[i2-1] - s[i1-1])/(i2-i1) >= (s[i-1] - s[i2-1]) / (i-i2)            --#ans[i][j] = {(i+1, j) | a[i] * (i-1)} + a[i] * j - ( {(i+1,j) | a[i] * i} + a[i] * i);            = a[i] * (j-i) - sum[i+1][j]            = a[i] * j - a[i] * i - (s[j] - s[i])            = a[i] * j - s[j] + (-a[i] * i + s[i])  //-f[i] = a[i] * i - s[i]            = a[i] * j - s[j] - f[i]; // g[j]            j1 < j2            g[j1] > g[j2]            a[i] * j1 - s[j1] - f[i] > a[i] * j2 - s[j2] - f[i]            a[i] * j1 - s[j1] > a[i] * j2 - s[j2]            a[i] * (j1-j2) > s[j1] - s[j2]            (s[j1] - s[j2])/(j1-j2) < a[i] //ll(j2, j1)j < j1 < j2ll(j1, j) >= (j2, j1) (s[j] - s[j1])/(j-j) >= (s[j1] - s[j2])/(j1-j2)  >    >ans = max(max(#ans[i]) + init)*/int a[N];LL sum[N];int tot;struct point{    LL a, s;    LL get(int i) {        return a * i - s;    }};point que[N];bool judge(point i1, point i2, point i) {    return (i.s - i2.s) * (i2.a - i1.a) <= (i2.s - i1.s) * (i.a - i2.a);}void insert(LL a, LL s) {    point tmp;    tmp.a = a, tmp.s = s;    while(tot >= 2 && judge(que[tot-2], que[tot-1], tmp))        --tot;    que[tot++] = tmp;}LL query(int x) {    int l = -1, r = tot-1;    while(r-l>1) {        int mid = l+r>>1;        if(que[mid].get(x) <= que[mid+1].get(x))            l = mid;        else r = mid;    }    return que[r].get(x);}int main() {    int n;    scanf("%d", &n);    LL ans = 0, init= 0;    sum[0] = 0;    for(int i = 1; i <= n; ++i) {        scanf("%d", &a[i]);        init += (LL)a[i] * i;        sum[i] = sum[i-1] + a[i];    }    tot = 0;    for(int i = 2; i <= n; ++i) {        insert(i-1, sum[i-2]);        ans = max(ans, query(a[i]) + sum[i-1] - (LL)a[i] * i);    }    tot = 0;    for(int i = n-1; i >= 1; --i) {        insert(-(i+1), sum[i+1]);        ans = max(ans, query(-a[i]) - (LL)a[i] * i + sum[i]);    }    printf("%I64d\n", ans + init);}


0 0