P3291-[SCOI2016]妖怪【凸壳】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P3291


1|1题目大意

给出 n 个数字对 (atk,dnf),求一个(a,b)

对于每个数字对可以选择任意一个实数k让其变为(atk+k×a,dnfk×a),但是操作完之后两个数字都非负。记atk/dnf(a,b)表示在(a,b)atk/dnf的最大值。

然后要求最小化max{atki(a,b),dnfi(a,b)}

1n106,1atk,dnf108


1|2解题思路

首先视(atk,dnf)为一个点的话,那么对于任意一个(a,b)答案肯定是在上凸壳上的。

然后考虑实际上我们并不需要用到(a,b)只需考虑ba的值,定义k=ba

然后就是要求最小化(用aiatkididnfi

ai+bi+aik+bi1k

考虑这个点在k的哪些区间由它取到最大值,对于一个j需要满足

ai+bi+aik+bi1k>aj+bj+ajk+bj1k

化一下

(aiaj)k2+(aiaj+bibj)k+(bibj)>0

然后就是一个二次不等式,并且考虑到j只需考虑凸壳上i左右连接的两个点,解出来我们可以得到k的合法范围。

然后上面那个是一个对钩函数,现在只需在这个范围内求这个对钩函数的最小值就好了。

时间复杂度O(nlogn)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=1e6+10; struct node{ double x,y; }p[N],s[N]; int n,top;double ans; bool calc(double a,double b,double c,double &l,double &r){ double d=b*b-4.0*a*c; if(d<0)return 0;d=sqrt(d); double x0=(-b-d)/(2*a),x1=(-b+d)/(2*a); if(x0>x1)swap(x0,x1);l=x0;r=x1; return 1; } bool cmp(node x,node y) {return (x.x==y.x)?(x.y>y.y):(x.x<y.x);} double solpe(node x,node y) {return (y.y-x.y)/(y.x-x.x);} int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); sort(p+1,p+1+n,cmp); for(int i=1;i<=n;i++){ while(top>1&&solpe(s[top-1],s[top])<=solpe(s[top-1],p[i]))top--; s[++top]=p[i]; } ans=1e18; for(int i=1;i<=top;i++){ double z=sqrt(s[i].y/s[i].x); double l=0,r=1e18,L=1,R=1;bool flag=1; if(i>1)calc(s[i].x-s[i-1].x,s[i].x-s[i-1].x+s[i].y-s[i-1].y,s[i].y-s[i-1].y,L,R); if(i<top)flag&=calc(s[i].x-s[i+1].x,s[i].x-s[i+1].x+s[i].y-s[i+1].y,s[i].y-s[i+1].y,l,r); if(!flag)continue; if(L<l)l=max(R,l);if(R>r)r=min(r,L); if(l>r||r<=0)continue;z=max(z,l);z=min(z,r); if(z>L&&z<R){ if(L>=l)ans=min(ans,s[i].x+s[i].y+s[i].x*L+s[i].y/L); if(R<=r)ans=min(ans,s[i].x+s[i].y+s[i].x*R+s[i].y/R); } else ans=min(ans,s[i].x+s[i].y+s[i].x*z+s[i].y/z); } printf("%.4lf\n",ans); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15225829.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(36)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示