zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    简单的使用SLF4J门面和log4j
    详细的Log4j使用教程
    java的Mybatis动态代理方式(二)
    java的一个基础的Mybatis例子(一)
    java的注解学习
    ArrayList输出的几种方法
    自己写的一个java链接数据库的类
    ipv4的TCP的几个状态 (SYN, FIN, ACK, PSH, RST, URG)
    tomcat的CATALINA_HOME环境变量可以不用设置
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5252172.html
Copyright © 2011-2022 走看看