zoukankan      html  css  js  c++  java
  • Codeforces Round #344 (Div. 2) E. Product Sum 维护凸壳

    E. Product Sum

    题目连接:

    http://www.codeforces.com/contest/631/problem/E

    Description

    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 values ai 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.

    Input

    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.

    Output

    Print a single integer — the maximum possible value of characteristic of a that can be obtained by performing no more than one move.

    Sample Input

    4
    4 3 2 5

    Sample Output

    39

    Hint

    题意

    给你n个数,每个数是a[i]

    然后所有数的答案就是sigma(i*a[i])

    现在你可以随便交换两个数的位置

    问你最后最大的答案是多少

    题解:

    考虑这个数和后面的数交换,那么增加的值是a[l]*(r-l)-(a[l+1]+...+a[r])

    和前面的交换的话,a[r]*(l-r)+(a[l]+...+a[r-1])

    然后我们分开考虑,先考虑和前面交换的

    可以化简为(a[r]*l-sum[l-1])+(sum[r-1]-a[r]*r),显然我们直接暴力枚举r,然后找到一个最大的(a[r]*l-sum[l-1])就好了

    这个东西可以抽象成在平面上的很多直线,斜率为l,截距为-sum[l-1]。

    每一个决策可以看成平面上的点,当然我们只会选凸包上的点咯,然后不断维护这个凸包就好了。

    考虑和后面交换同理。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+7;
    int n;
    long long sum[maxn];
    long long ans,dans;
    long long a[maxn];
    struct Convex_Hull
    {
        int sz;
        pair<long long,long long> line[maxn];
        void init()
        {
            memset(line,0,sizeof(line));
            sz=0;
        }
        long long get(int p,long long x)
        {
            return line[p].first*x+line[p].second;
        }
        bool is_bad(long long x,long long y,long long z)
        {
            long long fi = (line[x].second-line[z].second)*(line[x].first-line[y].first);
            long long se = (line[y].second-line[x].second)*(line[z].first-line[x].first);
            return fi<=se;
        }
        void add(long long x,long long y)
        {
            line[sz++]=make_pair(x,y);
            while(sz>2&&is_bad(sz-2,sz-3,sz-1))
                line[sz-2]=line[sz-1],sz--;
        }
        long long query(long long x)
        {
            int l = -1 ,r = sz-1;
            while(r-l>1)
            {
                int mid = (l+r)/2;
                if(get(mid,x)<=get(mid+1,x))l=mid;
                else r=mid;
            }
            return get(r,x);
        }
    }H;
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum[i]=sum[i-1]+a[i];
            ans=ans+a[i]*i;
        }
        H.init();
        for(int i=2;i<=n;i++)
        {
            H.add(i-1,-sum[i-2]);
            dans=max(dans,H.query(a[i])+sum[i-1]-a[i]*i);
        }
        H.init();
        for(int i=n-1;i>=1;i--)
        {
            H.add(-(i+1),-sum[i+1]);
            dans=max(dans,H.query(-a[i])+sum[i]-a[i]*i);
        }
        cout<<ans+dans<<endl;
    }
  • 相关阅读:
    python学习day02
    鼓起勇气 大胆说不
    spring系列---- spring-mvc1
    win7-64位 jdk安装
    项目分层以及阶段期限规划
    老油条之记
    论软件与管理的关系---企业管理软件的末路
    软件项目管理之觞
    世界在变化-----谷歌不安全
    LPR利率与固定利率哪个更合算?
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5243768.html
Copyright © 2011-2022 走看看