提供一个本质相同,但是不需要会向量也能做,而且很好想的方法。
首先发现凸包点少,也就意味着边少,考虑从边的方向寻找突破口。
考虑一个凸包的本质:若干个直线划分出若干个半平面,它们的交即为这个凸包。如果一个点对于每一条直线,都在于凸包的同侧,那么这个点就在这个凸包内。
这样直接暴力做仍然是 \(O(nmq)\) 的。但是明显发现每条直线相当于限制了,经过一个点 \((x,y)\),斜率为 \(k\) 的直线的截距不小于/大于某个数。取其中最大/小的一个限制即可。\(O(nm)\) 预处理出来,\(O(nq)\) 解决。
要注意的是,这种写法细节比较多。平行于坐标轴的情况建议全部特判,test 5 极度卡精度,可以手写分数类解决。
比向量解法相对复杂,但是也很好写。
code:
点击查看代码
int n,m,q,a[N],b[N],op[N];
const double eps=1e-8;
struct frac{
ll a,b;
frac(ll _a=0,ll _b=1){
a=_a,b=_b;
if(b<0)a=-a,b=-b;
}
il bool operator<=(const frac &tmp)const{
return (__int128)a*tmp.b<=(__int128)tmp.a*b;
}
il bool operator<(const frac &tmp)const{
return (__int128)a*tmp.b<(__int128)tmp.a*b;
}
il frac operator-(const frac &tmp)const{
return frac(a*tmp.b-b*tmp.a,b*tmp.b);
}
il frac operator*(const frac &tmp)const{
return frac(a*tmp.a,b*tmp.b);
}
}f[N],sl[N];
void check(int i,int j){
if(a[i]==a[j]){
if(b[i]<b[j])op[i]=2;
else op[i]=4;
}else if(b[i]==b[j]){
if(a[i]>a[j])op[i]=3;
else op[i]=5;
}else{
sl[i]=frac(b[i]-b[j],a[i]-a[j]);
if(a[i]<a[j])op[i]=0;
else op[i]=1;
}
}
void Yorushika(){
scanf("%d",&n);
rep(i,1,n){
scanf("%d%d",&a[i],&b[i]);
if(i==1)
continue;
check(i,i-1);
}
check(1,n);
rep(i,1,n){
if(op[i]>=1&&op[i]<=3)f[i]=frac(-1ll*inf*inf,1);
else f[i]=frac(1ll*inf*inf,1);
}
scanf("%d",&m);
rep(j,1,m){
int x,y;
scanf("%d%d",&x,&y);
rep(i,1,n){
frac nx=frac(x+a[i],1),ny=frac(y+b[i],1);
if(op[i]==0)f[i]=min(f[i],ny-nx*sl[i]);
else if(op[i]==1)f[i]=max(f[i],ny-nx*sl[i]);
else if(op[i]==2)f[i]=max(f[i],nx);
else if(op[i]==3)f[i]=max(f[i],ny);
else if(op[i]==4)f[i]=min(f[i],nx);
else f[i]=min(f[i],ny);
}
}
scanf("%d",&q);
rep(j,1,q){
frac x,y;
scanf("%lld%lld",&x.a,&y.a);
bool flag=true;
rep(i,1,n){
if(op[i]==0)flag&=y-x*sl[i]<=f[i];
else if(op[i]==1)flag&=f[i]<=y-x*sl[i];
else if(op[i]==2)flag&=f[i]<=x;
else if(op[i]==3)flag&=f[i]<=y;
else if(op[i]==4)flag&=x<=f[i];
else flag&=y<=f[i];
}
if(flag)
puts("Yes");
else
puts("No");
}
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}
题外话:
zlt 怎么又做过?zlt 怎么又做过?zlt 怎么又做过?
标签:直线,frac,ABC251G,ll,凸包,zlt,op From: https://www.cnblogs.com/yinhee/p/ABC251G.html