比較顯然的一個性質是若是存在$a(i)>=a(j) \& \& b(i)>=b(j)$那麼j沒用。html
咱們並不須要A,B的具體取值,咱們之關心$\frac {A}{B}$。node
不妨令B=1,x=A,那麼$t=\frac {x}{a} + \frac {1}{b}$。ios
那麼問題轉化爲:是否存在一個x使i的t最小。spa
顯然是一個上凸包,用單調棧維護便可。htm
關於單調棧維護凸包能夠看這篇博客。blog
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<map> #define int LL #define pair pair<int,int> #define MP(a,b) make_pair(a,b) #define LL long long using namespace std; const long double eps=0; struct node { LL a,b,id,is; #define a(i) A[i].a #define b(i) A[i].b #define id(i) A[i].id #define is(i) A[i].is long double xl(){return 1.0/a;} long double jj(){return 1.0/b;} friend bool operator < (node a,node b) {return a.a==b.a?a.b<b.b:a.a>b.a;} }A[500010],B[500010]; bool cmp1(node a,node b){return a.a==b.a?a.b<b.b:a.a<b.a;} bool cmp2(node a,node b){return a.b==b.b?a.a<b.a:a.b<b.b;} bool cmp3(node a,node b){return a.a<b.a;} //long double get(node a,node b){return (long double)(1.0/b.b-1.0/a.b)/(1.0/a.a-1.0/b.a);} long double get(node a,node b){return (long double)(1.0*(a.b-b.b)*a.a*b.a)/(1.0*(b.a-a.a)*a.b*b.b);} int n;bool al[510000]; map<pair,bool>mp; map<LL,int>ca; int sta[510000],top; #define ST sta[top] signed main() { // freopen("slay2.in","r",stdin); // freopen("1.out","w",stdout); cin>>n; for(int i=1;i<=n;i++)cin>>a(i)>>b(i),id(i)=i,B[i]=A[i],is(i)=1; sort(A+1,A+n+1,cmp1);int maxb=b(n); for(int i=n-1;i;i--) { if(maxb>=b(i))is(i)=0; maxb=max(maxb,b(i)); } sort(A+1,A+n+1); for(int i=1;i<=n;i++) if(is(i)) { while(top>1&&get(A[i],A[sta[top-1]])-get(A[ST],A[sta[top-1]])>eps)top--; if(top<=1|| (get(A[i],A[ST])>0) )sta[++top]=i; } for(int i=1;i<=top;i++)mp[MP(a(sta[i]),b(sta[i]))]=1; for(int i=1;i<=n;i++)if(mp[MP(B[i].a,B[i].b)])printf("%lld ",i); }