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

来源:互联网 发布:万方数据库中检索字段 编辑:程序博客网 时间:2024/06/09 21:56

题目链接点这里

我们先把a从小到大排序,询问x从小到大排序

我们可以发现,对于某对 ai和a(i+1)..如果我们有xi,此时取a(i+1)可以使xi的函数值最大的话,那么对于任意大于xi的x,取a(i+1)都比a(i)优,,所以我们就可以删除a(i),这就达到了斜率优化的要求。。。

推一下关系式可得,,我们需要维护一个斜率不断上升的凸包,,然后对于x,我们需要二分找到<=x的最大斜率,,这个就是x的最大值时的点。。


#include<algorithm>#include<iostream>#include<cmath>using namespace std;#define mem(x,y) memset(x,y,sizeof(x))#define FIN freopen("input.txt","r",stdin)#define fuck(x) cout<<x<<endlconst double  eps=1e-7;const int MX=111111;#define INF 0x3f3f3f3f#define INFLL 0x3f3f3f3f3f3f3f3ftypedef long long LL;typedef pair<LL,LL> PLL;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n,m,nn;struct Nod{    LL a,b;    bool operator <(const Nod x) const    {        if(a!=x.a) return a<x.a;        return b>x.b;    }};Nod arr[MX];Nod w[MX];double xielv[MX];LL erfeng(int l,int r,LL x){    int m;    while(l<r)    {        m=((l+r)>>1)+1;        if(fabs(xielv[m]-x)>eps&&xielv[m]>x)r=m-1 ;        else l=m;    }    return w[l].a*x+w[l].b;}LL getup(Nod a,Nod b){    return -a.b-(-b.b);}LL getdown(Nod a,Nod b){    return a.a-b.a;}int main(){    //FIN;    while(cin>>n>>m)    {        for(int i=0; i<n; i++)        {            LL a,b;            scanf("%I64d%I64d",&arr[i].a,&arr[i].b);        }        sort(arr,arr+n);        nn=0;        for(int i=0; i<n; i++)        {            if(i&&arr[i].a==arr[i-1].a)continue;            while(nn>=2&&getup(w[nn-2],w[nn-1])*getdown(w[nn-1],arr[i])>=getup(w[nn-1],arr[i])*getdown(w[nn-2],w[nn-1]))nn--;            w[nn++]=arr[i];        }        for(int i=0; i<nn; i++)        {            if(i==0)xielv[i]=-INF;            else xielv[i]=(double)getup(w[i-1],w[i])/getdown(w[i-1],w[i]);        }        for(int i=0; i<m; i++)        {            LL x;            scanf("%I64d",&x);            printf("%I64d\n",erfeng(0,nn-1,x));        }    }    return 0;}


0 0