Comet OJ - Contest #7 D 机器学习题 斜率优化 + 未调完

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\n",i,S[head],ans);    
    }                      
    printf("%lld\n",ans);    
    return 0;   
}

  

posted @ 2019-07-26 10:22  EM-LGH  阅读(157)  评论(0编辑  收藏  举报