传送门
题解:
很显然的半平面交,需要注意几个细节。
首先三线交于一点的时候中间那个点不能弹,然后重合的直线显然结果是相同的,再就是必须在第一象限。
由于给的就是解析式,直接用解析式做半平面交就行了,我的写法没有用double
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int N=2e4+7;
int k[N],b[N],id[N],st[N],tp;
bool cov(int i,int j){
return k[j]>=k[i]&&b[j]>b[i];
}
bool judge(int x,int y,int z){
return (ll)(k[z]-k[y])*(b[x]-b[z])>(ll)(k[z]-k[x])*(b[y]-b[z]);
}
bool cmp(int i,int j){
return k[i]<k[j]||(k[i]==k[j]&&b[i]<b[j]);
}
int n;
void Main(){
scanf("%d",&n);
for(int re i=1;i<=n;++i)scanf("%d",b+i);
for(int re i=1;i<=n;++i)scanf("%d",k+i);
for(int re i=1;i<=n;++i)id[i]=i;
std::sort(id+1,id+n+1,cmp);
for(int re i=1;i<=n;++i){
while(tp&&cov(st[tp],id[i]))--tp;
while(tp>1&&judge(st[tp-1],st[tp],id[i]))--tp;
st[++tp]=id[i];
}std::sort(st+1,st+tp+1);std::cout<<tp<<"\n";
for(int re i=1;i<=tp;++i)std::cout<<st[i]<<" ";
}
void file(){
#ifdef zxyoi
freopen("race.in","r",stdin);
#endif
}
signed main(){file();Main();return 0;}