日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P3291-[SCOI2016]妖怪【凸壳】

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3291-[SCOI2016]妖怪【凸壳】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P3291


題目大意

給出 nnn 個數字對 (atk,dnf)(atk,dnf)(atk,dnf),求一個(a,b)(a,b)(a,b)

對于每個數字對可以選擇任意一個實數kkk讓其變為(atk+k×a,dnf?k×a)(atk+k\times a,dnf-k\times a)(atk+k×a,dnf?k×a),但是操作完之后兩個數字都非負。記atk/dnf(a,b)atk/dnf(a,b)atk/dnf(a,b)表示在(a,b)(a,b)(a,b)atk/dnfatk/dnfatk/dnf的最大值。

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

1≤n≤106,1≤atk,dnf≤1081\leq n\leq 10^6,1\leq atk,dnf\leq 10^81n106,1atk,dnf108


解題思路

首先視(atk,dnf)(atk,dnf)(atk,dnf)為一個點的話,那么對于任意一個(a,b)(a,b)(a,b)答案肯定是在上凸殼上的。

然后考慮實際上我們并不需要用到(a,b)(a,b)(a,b)只需考慮ba\frac{b}{a}ab?的值,定義k=bak=\frac{b}{a}k=ab?

然后就是要求最小化(用aia_iai?atkiatk_iatki?did_idi?dnfidnf_idnfi?
ai+bi+aik+bi1ka_i+b_i+a_ik+b_i\frac{1}{k}ai?+bi?+ai?k+bi?k1?
考慮這個點在kkk的哪些區間由它取到最大值,對于一個jjj需要滿足
ai+bi+aik+bi1k>aj+bj+ajk+bj1ka_i+b_i+a_ik+b_i\frac{1}{k}>a_j+b_j+a_jk+b_j\frac{1}{k}ai?+bi?+ai?k+bi?k1?>aj?+bj?+aj?k+bj?k1?
化一下
(ai?aj)k2+(ai?aj+bi?bj)k+(bi?bj)>0(a_i-a_j)k^2+(a_i-a_j+b_i-b_j)k+(b_i-b_j)>0(ai??aj?)k2+(ai??aj?+bi??bj?)k+(bi??bj?)>0
然后就是一個二次不等式,并且考慮到jjj只需考慮凸殼上iii左右連接的兩個點,解出來我們可以得到kkk的合法范圍。

然后上面那個是一個對鉤函數,現在只需在這個范圍內求這個對鉤函數的最小值就好了。

時間復雜度O(nlog?n)O(n\log n)O(nlogn)


code

#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; }

總結

以上是生活随笔為你收集整理的P3291-[SCOI2016]妖怪【凸壳】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。