解题思路:
先求凸包。
合法向量相当于凸包A中存在一点经过该向量可到凸包B中。
即
A+v⃗ =B
A
+
v
→
=
B
,那么
v⃗ =A−B
v
→
=
A
−
B
画图发现,这些向量的轮廓就是凸包A绕取反后凸包B坐标平移一圈。
好像这个东西也叫Minkowski sum,即求
{v⃗ =a⃗ +b⃗ ,a⃗ ∈A,b⃗ ∈B}
{
v
→
=
a
→
+
b
→
,
a
→
∈
A
,
b
→
∈
B
}
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=100005;
struct point
{
ll x,y;
point(ll _x=0,ll _y=0):x(_x),y(_y){}
inline friend point operator + (const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
inline friend point operator - (const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
inline friend ll operator * (const point &a,const point &b){return a.x*b.y-a.y*b.x;}
inline ll dis(){return x*x+y*y;}
}p[N],p1[N],p2[N],t[N],v1[N],v2[N];
inline bool cmp(const point &a,const point &b)
{
ll ret=(a-t[1])*(b-t[1]);
if(ret)return ret>0;
else return (a-t[1]).dis()<(b-t[1]).dis();
}
int n,m,tot,Q;
int Graham(point *p,int cnt)
{
for(int i=1;i<=cnt;i++)t[i]=p[i];
for(int i=2;i<=cnt;i++)if(t[i].x<t[1].x||t[i].x==t[1].x&&t[i].y<t[1].y)swap(t[1],t[i]);
sort(t+2,t+cnt+1,cmp);int top=1;
for(int i=2;i<=cnt;i++)
{
while(top>=2&&(t[top]-t[top-1])*(t[i]-t[top-1])<=0)top--;
t[++top]=t[i];
}
for(int i=1;i<=top;i++)p[i]=t[i];
return top;
}
void go()
{
for(int i=1;i<=n;i++)v1[i]=p1[i%n+1]-p1[i];
for(int i=1;i<=m;i++)v2[i]=p2[i%m+1]-p2[i];
int l1=1,l2=1;p[tot=1]=p1[1]+p2[1];
while(l1<=n&&l2<=m)p[++tot]=p[tot-1]+(v1[l1]*v2[l2]>=0?v1[l1++]:v2[l2++]);
while(l1<=n)p[++tot]=p[tot-1]+v1[l1++];
while(l2<=m)p[++tot]=p[tot-1]+v2[l2++];
tot=Graham(p,tot);
}
int in(point x)
{
if((x-p[1])*(p[2]-p[1])>0||(x-p[1])*(p[tot]-p[1])<0)return 0;
int l=2,r=tot,pos=l;
while(l<=r)
{
int mid=l+r>>1;
if((p[mid]-p[1])*(x-p[1])>=0)pos=mid,l=mid+1;
else r=mid-1;
}
return (p[pos%tot+1]-p[pos])*(x-p[pos])>=0;
}
int main()
{
//freopen("war.in","r",stdin);
//freopen("war.out","w",stdout);
n=getint(),m=getint(),Q=getint();
for(int i=1;i<=n;i++)p1[i].x=getint(),p1[i].y=getint();
for(int i=1;i<=m;i++)p2[i].x=-getint(),p2[i].y=-getint();
n=Graham(p1,n),m=Graham(p2,m);
go();
while(Q--)
{
point q;q.x=getint(),q.y=getint();
printf("%d\n",in(q));
}
return 0;
}