S/s+R/r=(S,R)*(1/s,1/r)
从上面的式子可以看出,向量(1/s,1/r)在向量(S,R)上的分量最小的就是最后赢的那个,这其实就是靠近原点那侧的闭包
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define DEBUG_OUT(a) cout<<a<<endl
// #define DEBUG_OUT(a)
#define print_list(a,s) for(int i=0;i<s;++i)cout<<a[i].x<<" "<<a[i].y<<endl;
using namespace std;
typedef long long int LL;
struct Point {int x, y;};
bool compare(Point a,Point b)
{
return (a.x < b.x) || (a.x == b.x && a.y < b.y);
}
//Andrew's Monotone Chain
class find_convex_hull
{
// 向量OA cross 向量OB。大於零表示從OA到OB為順時針旋轉。
LL cross(Point& o, Point& a, Point& b)
{
LL ox=o.x,oy=o.y;
LL ax=a.x,ay=a.y;
LL bx=b.x,by=b.y;
// return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
return (ox-ax)*(oy-by)*bx*ay-(oy-ay)*(ox-bx)*ax*by;
}
// 小於。依座標大小排序,先排 x 再排 y。
public:
// P為平面上的那些點。這裡設定為剛好100點。
// CH為凸包上的點。這裡設定為照逆時針順序排列。
void findConvexHull(Point* P,Point* CH,int size,int& m)
{
// 將所有點依照座標大小排序
sort(P, P+size, compare);
// print_list(P,size);
// int m = 0; // m 為凸包頂點數目
m=0;
// 包下半部
for (int i=0; i<size; ++i) {
while (m >= 2 && cross(CH[m-2], CH[m-1], P[i]) < 0) m--;
CH[m++] = P[i];
}
// 包上半部,不用再包入方才包過的終點,但會再包一次起點
for (int i=size-2, t=m+1; i>=0; --i) {
while (m >= t && cross(CH[m-2], CH[m-1], P[i]) < 0) m--;
CH[m++] = P[i];
}
}
};
void add_to_res(vector<int>&res,vector<int>&t)
{
// cout<<"to add"<<endl;
for(int i=0;i<t.size();++i)
{
// cout<<"add:"<<t[i]<<endl;
res.push_back(t[i]);
}
}
bool equal(Point& a,Point& b)
{
return (a.x==b.x)&&(a.y==b.y);
}
int main()
{
const int max_n=10010;
Point candidates[max_n];
int dist[max_n];
vector<int> dist_count[max_n];
memset(dist , 0,sizeof(dist));
int n;
cin>>n;
do{
int s,r;
for(int i=0;i<n;++i)
{
cin>>s>>r;
if(dist[s]==r)
{
dist_count[s].push_back(i+1);
}else if(dist[s]<r){
dist[s]=r;
dist_count[s].clear();
dist_count[s].push_back(i+1);
}
}
}while(false);
int nc=0;
Point L,R;
L.y=-1;
for(int i=0;i<max_n;++i)
{
if(dist[i]!=0)
{
candidates[nc].x=i;
candidates[nc].y=dist[i];
R.x=i;
R.y=dist[i];
if(L.y<=dist[i])
{
L=R;
}
++nc;
}
}
Point CH[max_n<<1];
int m=0;
find_convex_hull fch;
fch.findConvexHull(candidates, CH,nc,m);
vector<int> res;
bool toadd=false;
int i=0;
--m;
while(true)
{
Point p=CH[i%m];
// cout<<p.x<<" "<<p.y<<endl;
if(toadd)
{
add_to_res(res,dist_count[p.x]);
}
if(equal(p,R))
{
add_to_res(res,dist_count[p.x]);
toadd=true;
}
if(equal(p,L)&&toadd)
{
break;
}
++i;
}
sort(res.begin(),res.end());
for(int i=0;i<res.size();++i)
{
cout<<res[i]<<" ";
}
cout<<endl;
}