jzoj4640. 【GDOI2017模拟7.15】妖怪

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

3
1 1
1 2
2 2

Sample Output

8.0000
在这里插入图片描述

Data Constraint

在这里插入图片描述

题解

我还挺喜欢数学的呢
这题一眼看上去不会,化化式子没想到未知数竟然是一个反比例+一次函数的样子。
长这样:ax+bx\frac a x+bxxa+bx
当时心态就没了。
原来这玩意是一个在高中叫做双勾函数(或对勾函数或耐克函数
很好,于是我们就看看这个玩意长什么样——
在这里插入图片描述
既然是长这个样子,那么应该就有一个顶点(最小点)。
利用均值不等式可以得到——
(aba,2ab)(\frac{\sqrt{ab}}a,2\sqrt{ab})(aab,2ab)
由于图中有很多很多的双勾函数,那么其中必然有一些线没有用的。
我们考虑删去这些没有用的

怎么删?
首先我们对于任意两点——满足
ai&lt;aj且yi&lt;yj(答案)a_i&lt;a_j且y_i&lt;y_j(答案)ai<ajyi<yj
那么
ai+bi+ai∗x+bix&lt;aj+bj+aj∗x+bjxa_i+b_i+a_i*x+\frac{b_i}{x}&lt;a_j+b_j+a_j*x+\frac{b_j}{x}ai+bi+aix+xbi<aj+bj+ajx+xbj
化一波式子得到:
x&gt;bi−bjaj−aix&gt;\frac{b_i-b_j}{a_j-a_i}x>ajaibibj
c[i,j]=bi−bjaj−aic[i,j]=\frac{b_i-b_j}{a_j-a_i}c[i,j]=ajaibibj
则我们对于一个c[i,j]&gt;c[j,k]c[i,j]&gt;c[j,k]c[i,j]>c[j,k]那么j这个点就是没有用的。
所以说,我们就得到一个序列ddd,序列满足c[di−1,di]&lt;c[di,di+1]c[d_{i-1},d_i]&lt;c[d_i,d_{i+1}]c[di1,di]<c[di,di+1]
这个东东是递增的。
那么我们发现:当xxxc[di−1,di]c[d_{i-1},d_i]c[di1,di]c[di,di+1]c[d_i,d_{i+1}]c[di,di+1]这段区间内时,did_idi的函数值是最大的。
因此,我们在did_idi的函数上判断这段区间的最小值即可。
怎么判断?可能有三种情况:
1、在顶点左边。
2、在顶点右边。
3、横跨顶点。

O(n)O(n)O(n)求即可。

代码
var
        i,j,k,l,n,m,now:longint;
        a,b,d:array[0..1000003] of longint;
        op,oq,x,y,ans,aa,bb:extended;
function min(x,y:extended):extended;
begin
        if x<y then exit(x);exit(y);
end;
procedure qsort(l,r:longint);
var
        i,j,m,m1:longint;
begin
        i:=l;j:=r;
        m:=a[(l+r) div 2];
        m1:=b[(l+r) div 2];
        repeat
                while (a[i]<m) or ((a[i]=m) and (b[i]<m1)) do inc(i);
                while (a[j]>m) or ((a[j]=m) and (b[j]>m1)) do dec(j);
                if i<=j then
                begin
                        a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
                        b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
                        inc(i);dec(j);
                end;
        until i>j;
        if l<j then qsort(l,j);
        if r>i then qsort(i,r);
end;
function pd(i:longint):boolean;
var
        x,y,op,oq:extended;
begin
        x:=b[d[now]]-b[d[now-1]];
        y:=a[d[now-1]]-a[d[now]];
        op:=x/y;
        x:=b[i]-b[d[now]];
        y:=a[d[now]]-a[i];
        oq:=x/y;
        if op>oq then exit(true);
        exit(false);
end;
begin
        //assign(input,'monster.in');reset(input);
        readln(n);
        for i:=1 to n do
        begin
                read(a[i],b[i]);
        end;
        qsort(1,n);
        now:=1;
        d[1]:=1;
        for i:=2 to n do
        begin
                if a[i]>a[1] then
                begin
                        inc(now);
                        d[now]:=i;
                        j:=i;
                        break;
                end;
        end;
        for i:=j+1 to n do
        begin
                if a[i]>a[d[now]] then
                begin
                        while (now>=2) and (pd(i)) do dec(now);
                        inc(now);d[now]:=i;
                end;
        end;
        ans:=maxlongint;
        for i:=2 to now-1 do
        begin
                x:=b[d[i]]-b[d[i-1]];
                y:=a[d[i-1]]-a[d[i]];
                op:=x/y;
                x:=b[d[i+1]]-b[d[i]];
                y:=a[d[i]]-a[d[i+1]];
                oq:=x/y;
                aa:=a[d[i]];
                bb:=b[d[i]];
                if op>sqrt(aa*bb)/aa then ans:=min(ans,aa*op+bb/op+aa+bb);
                if oq<sqrt(aa*bb)/aa then ans:=min(ans,aa*oq+bb/oq+aa+bb);
                if (op<=sqrt(aa*bb)/aa) and (oq>=sqrt(aa*bb)/aa) then ans:=min(ans,2*sqrt(aa*bb)+aa+bb);
        end;
        x:=b[d[now]]-b[d[now-1]];
        y:=a[d[now-1]]-a[d[now]];
        aa:=a[d[now]];bb:=b[d[now]];
        op:=x/y;
        if op>sqrt(aa*bb)/aa then ans:=min(ans,aa*op+bb/op+aa+bb)
        else ans:=min(ans,2*sqrt(aa*bb)+aa+bb);
        writeln(ans:0:4);
end.

转载于:https://www.cnblogs.com/RainbowCrown/p/11148359.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值