convex hull trick CF344.E

Posted chenhuan001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了convex hull trick CF344.E相关的知识,希望对你有一定的参考价值。

类似于斜率优化的东西,果真CF的E以后才会考点算法啊。

感觉这种优化应该很常见,但这题直线只有第一象限的,但是插入,和查找操作是不变的,按极角排序后就可以直接用这个模板了。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;

typedef long long ll;

struct Line
{
    ll a,b;
    ll get(ll x)
    {
        return a*x+b;
    }
};

struct Convex_Hull
{
    int size;
    Line ls[200200];
    void init()
    {
        size=0;
    }
    bool is_bad(int one,int two,int three)//目前凸包集为xxx12  要将3插入,判断是否删除2
    {
        Line l1=ls[one],l2=ls[two],l3=ls[three];
        return (l2.b-l1.b)*(l1.a-l3.a)>=(l3.b-l1.b)*(l1.a-l2.a);//我这样肯定可以!
    }
    void add_line(ll a,ll b)
    {
        ls[size++] = Line{a,b};//这样写也可以?
        while(size>=3 && is_bad(size-3, size-2, size-1) )
        {
            ls[size-2] = ls[size-1]; size--;
        }
    }
    ll query(ll x)
    {
        int b=-1,d=size-1;
        while(d-b > 1)
        {
            int mid=(b+d)/2;
            if( ls[mid].get(x) <= ls[mid+1].get(x) )
            {
                b = mid;
            }
            else d = mid;
        }
        return ls[d].get(x);
    }
};

#define N 200200

ll sum[N];
ll ans,tans;
Convex_Hull cv;
int g[N];

int main() {
    int n;
    cin>>n;
    sum[0]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",g+i);
        sum[i] = sum[i-1]+g[i];
        ans += (ll)i*g[i];
    }
    cv.init();
    for(int i=2;i<=n;i++)
    {
        cv.add_line(i-1, -sum[i-2]);
        tans = max(tans,cv.query(g[i])+sum[i-1]-(ll)i*g[i]);
    }
    
    //第二遍,逆着写。
    cv.init();
    for(int i=n-1;i>=1;i--)
    {
        cv.add_line(-(i+1), -sum[i+1]);
        tans = max(tans,cv.query(-g[i])+sum[i]-(ll)i*g[i]);
    }
    cout<<ans+tans<<endl;
    return 0;
}

 

以上是关于convex hull trick CF344.E的主要内容,如果未能解决你的问题,请参考以下文章

Convex hull

Convex hull凸包

python库skimage 绘制二值图像的凸壳(convex hull)

Opencv Convex Hull (凸包)

R语言为散点图添加凸包(convex hull):数据预处理(创建一个包含每组数据凸包边界的数据集)ggplot2使用geom_polygon函数为可视化图像添加凸包(convex hull)

[算法课][分治]寻找凸包 (Convex Hull)