• Comet OJ


    Code: 

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define setIO(s) freopen(s".in","r",stdin) 
    #define maxn 400005 
    #define inf 1000000009
    #define ll long long  
    using namespace std;      
    int head,tail;    
    int S[maxn];
    ll le[maxn],ri[maxn],sumv[maxn],pos[maxn];   
    ll sqr(ll x) 
    {
        return 1ll*(1ll*x * 1ll*x);  
    } 
    struct Node 
    {
        ll x,y; 
    }nd[maxn];      
    bool cmp(Node a,Node b) 
    {
        return a.x<b.x;  
    }   
    ll Y(int f) 
    {
        return (ll)(ri[f]+1ll*f*f);           
    }
    ll X(int f) 
    { 
        return f;   
    } 
    double slope(int i,int j) 
    {
        return (double)(Y(i)-Y(j))/(double)(X(i)-X(j)); 
    }
    void insert(int x) 
    {       
        if(tail<2) 
        {
            if(tail==1) 
            {
                if(X(x)==XS[++tail]=x;  
            }
            else 
            {
                S[++tail]=x;  
            }
            return; 
        } 
        while(tail>1&&slope(S[tail-1], S[tail]) >= slope(S[tail-1], x)) --tail;      
        S[++tail]=x;            
    }
    int main() 
    {
        // setIO("input");      
        int n; 
        scanf("%d",&n);   
        for(int i=1;i<=n;++i) scanf("%lld%lld",&nd[i].x,&nd[i].y);                             
        sort(nd+1,nd+1+n,cmp);   
        nd[0].x=-inf; 
        for(int i=1;i<=n;++i) pos[i]=nd[i].x; 
        for(int i=1;i<=n;++i) 
        {
            sumv[i]=sumv[i-1]; 
            if(nd[i].y<0) sumv[i]-=nd[i].y;          
            le[i]=le[i-1];               
            if(nd[i-1].x!=nd[i].x) le[i]=sumv[i-1];                        
        }
        for(int i=1;i<=n;++i) sumv[i]=0;  
        nd[n+1].x=inf; 
        for(int i=n;i>=1;--i) 
        { 
            sumv[i]=sumv[i+1]; 
            if(nd[i].y>0) sumv[i]+=nd[i].y;  
            ri[i]=ri[i+1]; 
            if(nd[i+1].x!=nd[i].x) ri[i]=sumv[i+1];       
        }                       
        head=1; 
        long long ans=100000000000000000;  
        for(int i=1;i<=n;++i) insert(i);           
        for(int i=1;i<=n;++i)   
        {
            while(head<tail && pos[S[head]] < pos[i]) ++head;                   
            while(head<tail && slope(S[head], S[head+1]) < 2*pos[i]) ++head;   
            if(head>tail) break;  
            ans=min(ans, le[i] + sqr( (pos[i] - pos[S[head]]) ) + ri[S[head]]);    
            // printf("%d %d %lld
    ",i,S[head],ans);    
        }                      
        printf("%lld
    ",ans);    
        return 0;   
    }
    

      

  • 相关阅读:
    第二次作业
    动手动脑
    第五周总结
    第四周总结
    二维数组
    返回一个整数数组中最大子数组的和---第一次完善
    第三周总结
    第二周进度
    自我介绍
    返回一个整数数组中最大子数组的和
  • 原文地址:https://www.cnblogs.com/guangheli/p/11248662.html
Copyright © 2020-2023  润新知