FZU-2239 Daxia & Yayamao's problem(斜率优化)

来源:互联网 发布:我心伤悲 莫知我哀图片 编辑:程序博客网 时间:2024/06/05 01:56

Daxia & Yayamao's problem

 FZU - 2239 
题解:f(x)=A*x+B
如果j>k,Aj>Ak,Aj*x+Bj>=Ak*x+Bk,则(Bj-Bk)/(Aj-Ak)>=-x
说明如果j要比k优,那么斜率一定要大于-x,根据斜率优化,这样就需要构建上凸包


构建完凸包后,再用三分找最优点即可


#include<cstdio>#include<algorithm>using namespace std;const int MX = 1e5 + 5;typedef long long LL;struct node{    LL x,y;    node(){}    node(LL X,LL Y){x=X;y=Y;}    node operator-(node _A){        return node(x-_A.x,y-_A.y);    }    LL operator^(node _A){        return x*_A.y-y*_A.x;    }}p[MX];bool cmp(node p1,node p2){    if(p1.x!=p2.x) return p1.x<p2.x;    return p1.y<p2.y;}void convex(int &n){    int cnt=0;    for(int i=1;i<=n;i++){        while(cnt>=2&&((p[i]-p[cnt])^(p[cnt]-p[cnt-1]))<=0) cnt--;        p[++cnt]=p[i];    }    n=cnt;}LL f(int i,LL k){    return p[i].x*k+p[i].y;}int main(){    LL x;    int n,m;   // freopen("in.txt","r",stdin);    while(~scanf("%d%d",&n,&m)){        for(int i=1;i<=n;i++) scanf("%I64d%I64d",&p[i].x,&p[i].y);        sort(p+1,p+n+1,cmp);        convex(n);    //构建凸包        for(int i=1;i<=m;i++){            scanf("%I64d",&x);            int l=1,r=n;            //三分找最优点            while(l<r){                int mid=l+(r-l)/3;                int midr=r-(r-l)/3;                if(f(mid,x)<f(midr,x)) l=mid+1;                else r=midr-1;            }            printf("%I64d\n",max(f(l,x),f(r,x)));        }    }    return 0;}


0 0