• 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;
    }
  • 相关阅读:
    点名
    2017.6.11 NOIP模拟赛
    HEOI 2012 旅行问题
    【1】【JUC】JDK1.8源码分析之ReentrantLock
    Git撤销&回滚操作
    源码分析之CountDownLatch
    【1】AQS详解
    循环屏障CyclicBarrier以及和CountDownLatch的区别
    【JUC】CountDownLatch
    匿名内部类中使用的外部局部变量为什么只能是final变量
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5252172.html
Copyright © 2020-2023  润新知