斜率排序+半平面交
根据物理知识,我们可以用距离,速度,时间写出一个一次函数,那么本题就是问从y轴正方向无限远能看见多少条线(包括重合!),于是维护下凸壳
#include<cstdio>
#include<algorithm>
#define N 10005
using namespace std;
struct Line
{
double k, b;
int id;
friend bool operator < (Line a, Line b)
{
if(a.k!=b.k)return a.k<b.k;
else return a.b>b.b;
}
}L[N], s[N];
const double eps = 1e-8;
int top, ans[N];
double crossx(Line a, Line b)
{
return (b.b-a.b)/(a.k-b.k);
}
bool judge(Line a, Line b, Line c)
{
return crossx(a,c) < crossx(a,b);
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%lf",&L[i].b);
L[i].id=i;
}
for(int i = 1; i <= n; i++)
scanf("%lf",&L[i].k);
sort(L+1,L+1+n);
s[++top]=L[1];
ans[top]=L[1].id;
for(int i = 2; i <= n; i++)
{
if(L[i].k - s[top].k < eps && L[i].b < s[top].b)continue;
while(top && L[i].b > s[top].b)top--;
while(top>=2 && judge(s[top-1],s[top],L[i]))top--;
s[++top]=L[i];
ans[top]=L[i].id;
}
sort(ans+1,ans+1+top);
printf("%d\n",top);
for(int i = 1; i < top; i++)
printf("%d ",ans[i]);
printf("%d",ans[top]);
}