P4557 [JSOI2018]战争

P4557 [JSOI2018]战争

链接

P4557 [JSOI2018]战争

题解

闵可夫斯基和的板子题。
题目给了两个点集\(A\),\(B\),显然可以先把凸包搞出来。。
然后多次询问,每次询问一个向量是否满足存在 \(b+w\) \(=\) \(a\)
移项之后就是问是否满足存在\(w=a-b\) ,把\(B\)中的每个点坐标取反,然后求闵可夫斯基和就可以了。

\(Code\)

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e5+10;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void print(LL x){
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

struct P{
    LL x,y;
    LL len(){return x*x+y*y;}
    P(LL xx=0,LL yy=0){x=xx;y=yy;}
};
P operator - (P x,P y){return P(x.x-y.x,x.y-y.y);}
P operator + (P x,P y){return P(x.x+y.x,x.y+y.y);}
LL operator * (P x,P y){return x.x*y.y-x.y*y.x;}

bool cmp1(P x,P y){return x.y<y.y||(x.y==y.y&&x.x<y.x);}
bool cmp2(P x,P y){return x*y>0||(x*y==0&&x.len()<y.len());}
void Convex(P *A,int &n){
    sort(A+1,A+1+n,cmp1);
    P O=A[1];
    for(int i=2;i<=n;++i){
        A[i]=A[i]-A[1];
    }
    sort(A+2,A+1+n,cmp2);
    int tp=1;
    for(int i=2;i<=n;++i){
        while(tp>=3&&((A[i]-A[tp-1])*(A[tp]-A[tp-1])>=0)) --tp;
        A[++tp]=A[i];
    }
    n=tp;
    for(int i=2;i<=n;++i) A[i]=A[i]+O;
    return;
}
P D[N];

int tot;
int n,m,Q; 
P C1[N],C2[N],a1[N],a2[N];
void Minkowski(){
    for(int i=1;i<n;++i) a1[i]=C1[i+1]-C1[i];a1[n]=C1[1]-C1[n];
    for(int i=1;i<m;++i) a2[i]=C2[i+1]-C2[i];a2[m]=C2[1]-C2[m];
    D[tot=1]=C1[1]+C2[1];
    LL p1=1,p2=1;
    while(p1<=n&&p2<=m) ++tot,D[tot]=D[tot-1]+(a1[p1]*a2[p2]>=0?a1[p1++]:a2[p2++]);
    while(p1<=n) ++tot,D[tot]=D[tot-1]+a1[p1++];
    while(p2<=m) ++tot,D[tot]=D[tot-1]+a2[p2++];
}

int init(P E){
    if(E*D[2]>0||D[tot]*E>0) return 0;
    LL ps=lower_bound(D+1,D+tot+1,E,cmp2)-D-1;
    return (E-D[ps])*(D[ps%tot+1]-D[ps])<=0;
} 

int main(){
    scanf("%d%d%d",&n,&m,&Q);
    for(int i=1;i<=n;++i){
        scanf("%lld%lld",&C1[i].x,&C1[i].y);
    }
    for(int i=1;i<=m;++i){
        scanf("%lld%lld",&C2[i].x,&C2[i].y);
        C2[i].x=-C2[i].x;C2[i].y=-C2[i].y;
    }
    Convex(C1,n);
    Convex(C2,m);
    Minkowski();
    Convex(D,tot);
    P O=D[1],E;
    for(int i=1;i<=tot;++i) D[i]=D[i]-O;
    while(Q--){
        scanf("%lld%lld",&E.x,&E.y);
        printf("%d\n",init(E-O));
    }
    return 0;
}
posted @ 2020-10-15 20:39  Iscream-2001  阅读(112)  评论(0编辑  收藏  举报
/* */ /* */