[学习笔记] [JSOI2018] luogu P4557 战争 - 闵可夫斯基和 - 凸包 - 计算几何 - 学习笔记

闵可夫斯基和即,两个凸包按照边的斜率从小到大加入即可。
本题中 ∃ b + Δ ⊆ A ⇒ ∃ b , Δ ⊆ A − b ⇒ Δ ⊆ { a − b ∣ a ∈ A , b ∈ B } \exist b+\Delta\subseteq A\Rightarrow\exist b,\Delta\subseteq A-b\Rightarrow\Delta\subseteq\{a-b|a\in A,b\in B\} b+ΔAb,ΔAbΔ{abaA,bB}

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
    int x=0,ch,s=1;while(((ch=gc)<'0'||ch>'9')&&ch!='-');
    if(ch^'-') x=ch^'0';else s=-1;
    while((ch=gc)>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0');
    return s>0?x:-x;
}
const int N=100010;
struct P{
    int x,y;P(int _x=0,int _y=0) { x=_x,y=_y; }
    inline int input() { return x=inn(),y=inn(); }
    inline bool operator<(const P &p)const { return x==p.x?y<p.y:x<p.x; }
    inline P operator+(const P &p)const { return P(x+p.x,y+p.y); }
    inline P operator-(const P &p)const { return P(x-p.x,y-p.y); }
    inline bool operator==(const P &p)const { return x==p.x&&y==p.y; }
    inline lint len2()const { return (lint)x*x+(lint)y*y; }
};typedef vector<P> poly;poly A,B,q;
inline lint cross(const P &a,const P &b) { return (lint)a.x*b.y-(lint)a.y*b.x; }
inline lint cross(const P &s,const P &t1,const P &t2) { return cross(t1-s,t2-s); }
inline poly convexHull(poly ps,int nedsort=1)
{
    int n=(int)ps.size();if(n<=2) return ps;
    if(nedsort) sort(ps.begin(),ps.end());
    poly ans(n<<1);int k=0;
    for(int i=0;i<n;ans[k++]=ps[i++])
        while(k>1&&cross(ans[k-2],ans[k-1],ps[i])<=0) k--;
    for(int i=n-1,t=k;i>=0;ans[k++]=ps[i--])
        while(k>t&&cross(ans[k-2],ans[k-1],ps[i])<=0) k--;
    return ans.resize(k-1),ans;
}
inline poly minkowskiSum(poly A,poly B)
{
    poly ans,vA,vB;vA.clear(),vB.clear();
    int n=(int)A.size(),m=(int)B.size();
    ans.resize(n+m+1);
    Rep(i,A) vA.pb(A[(i+1)%n]-A[i]);
    Rep(i,B) vB.pb(B[(i+1)%m]-B[i]);
    ans[0]=A[0]+B[0];int i=0,j=0,k=1;
    while(i<n&&j<m)
        if(cross(vA[i],vB[j])>=0) ans[k]=ans[k-1]+vA[i++],k++;
        else ans[k]=ans[k-1]+vB[j++],k++;
    while(i<n) ans[k]=ans[k-1]+vA[i++],k++;
    while(j<m) ans[k]=ans[k-1]+vB[j++],k++;
    return convexHull(ans);
}
inline int incmp(const P &p1,const P &p2)
{
    lint k=cross(p1,p2);if(k) return k>0;
    return p1.len2()<=p2.len2();
}
inline int inconvex(P p,const poly &ps)
{
    int n=(int)ps.size();if(p==ps[n-1]) return 1;
    if(!incmp(p,ps[n-1])) return 0;
    int x=lower_bound(ps.begin(),ps.end(),p,incmp)-ps.begin()-1;
    return cross(p-ps[x],ps[x+1]-ps[x])<=0;
}
int main()
{
    A.resize(inn()),B.resize(inn());int q=inn();
    Rep(i,A) A[i].input();
    Rep(i,B) B[i].input(),B[i].x=-B[i].x,B[i].y=-B[i].y;
    A=convexHull(A),B=convexHull(B);
    A=minkowskiSum(A,B);P bas=A[0];
    Rep(i,A) A[i]=A[i]-bas;P p;
    rep(i,1,q) p.input(),printf("%d\n",inconvex(p-bas,A));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值