luogu P4557 [JSOI2018]战争
作者:互联网
https://www.luogu.com.cn/problem/P4557
给两个凸包\(A,B\),令\(a\in A,b \in B\),如果存在\(b+v=a\),那么\(v\)这个向量就会冲突
移项可得
\(v=a-b\),那么就变成判断\(v\)是否在\(A-B\)中
把\(A,B\)求个闵可夫斯基和,然后判断即可
具体的过程就是先对\(A,B\)分别跑凸包,把没用的点扔了
然后把选两个凸包的最低点,加起来作为起始点,在把两个凸包的边用向量表示出来,再求一遍凸包即可
没啥特别的细节
code:
#include<bits/stdc++.h>
#define N 200060
#define ll long long
using namespace std;
struct A {
ll x, y;
A operator + (const A &o) const {return (A){x + o.x, y + o.y};}
A operator - (const A &o) const {return (A){x - o.x, y - o.y};}
ll operator * (const A &o) const {return x * o.y - y * o.x;}
ll len() {return x * x + y * y;}
};
A vec(A x, A y) {
return y - x;
}
int cmpp(A x, A y) {
if(x.y != y.y) return x.y < y.y;
return x.x < y.x;
}
A bs;
int cmp(A x, A y) {
ll o = vec(bs, x) * vec(bs, y);
if(o > 0) return 1;
return o == 0 && vec(bs, x).len() < vec(bs, y).len();
}
int sta[N << 1];
void get(A *a, int &n) {
sort(a + 1, a + 1 + n, cmpp);
bs = a[1];
sort(a + 1 ,a + 1 + n, cmp);
int top = 0;
for(int i = 1; i <= n; i ++) {
while(top > 1 && vec(a[sta[top - 1]], a[i]) * vec(a[sta[top - 1]], a[sta[top]]) >= 0) top --;
sta[++ top] = i;
}
for(int i = 1; i <= top; i ++) a[i] = a[sta[i]];
n = top; a[n + 1] = a[1];
}
int n, m, q, gs;
A a[N], b[N], c[N], v1[N], v2[N];
void Mink() {
for(int i = 1; i <= n; i ++) v1[i] = vec(a[i], a[i + 1]);
for(int i = 1; i <= m; i ++) v2[i] = vec(b[i], b[i + 1]);
c[gs = 1] = a[1] + b[1];
int p1 = 1, p2 = 1;
while(p1 <= n && p2 <= m)
++ gs, c[gs] = c[gs - 1] + (v1[p1] * v2[p2] >= 0? v1[p1 ++] : v2[p2 ++]);
while(p1 <= n)
++ gs, c[gs] = c[gs - 1] + v1[p1 ++];
while(p2 <= n)
++ gs, c[gs] = c[gs - 1] + v2[p2 ++];
}
int in(A x) {
if(vec(c[1], c[gs]) * vec(c[1], x) > 0) return 0;
if(vec(c[1], x) * vec(c[1], c[2]) > 0) return 0;
int pos = lower_bound(c + 1, c + 1 + gs, x, cmp) - c - 1;
return vec(c[pos], c[pos % gs + 1]) * vec(c[pos], x) >= 0;
}
int main() {
scanf("%d%d%d", &n, &m, &q);
for(int i = 1; i <= n; i ++) scanf("%lld%lld", &a[i].x, &a[i].y);
get(a, n);
for(int i = 1; i <= m; i ++) scanf("%lld%lld", &b[i].x, &b[i].y), b[i].x *= -1, b[i].y *= -1;
get(b, m);
Mink();
get(c, gs);
while(q --) {
A x;
scanf("%lld%lld", &x.x, &x.y);
printf("%d\n", in(x));
}
return 0;
}
标签:return,P4557,luogu,ll,bs,int,vec,JSOI2018,const 来源: https://www.cnblogs.com/lahlah/p/15924660.html