ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu P4557 [JSOI2018]战争

2022-02-22 20:04:01  阅读:201  来源: 互联网

标签:return P4557 luogu ll bs int vec JSOI2018 const


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有