「JSOI2018」战争

解题思路

我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在

\[b\in B,(b+w)\in A
\]

这里 \(A, B\) 表示凸包内部的点集,可以转化一步变成

\[a\in A,b \in B,b+w=a \\ w =a -b
\]

那相当于对 \(A,(-B)\) 作闵可夫斯基和,判断 \(w\) 是否在新的凸包内部,把新的凸包划分成三角区域,让 \(w\) 和原点做一条向量,二分一下在哪个区域然后判断一下在区域内部还是外部就可以了,复杂度 \(\mathcal O(n \log n)\) 。

code

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1000005;
struct P{
ll x, y;
friend P operator + (P a, P b){ return (P){a.x + b.x, a.y + b.y}; }
friend P operator - (P a, P b){ return (P){a.x - b.x, a.y - b.y}; }
friend ll operator * (P a, P b){ return a.x * b.y - b.x * a.y; }
inline ll dis(){ return x * x + y * y; }
}A[N], B[N], C[N], s1[N], s2[N], st[N], O;
int n, m, q;
inline bool cmp1 (P A, P B){
return A.y != B.y ? A.y < B.y : A.x < B.x;
}
inline bool cmp2 (P A, P B){
//叉积一样按照离原点距离排,防止较远的点被近的点日掉
ll res = (A - O) * (B - O);
return res ? res > 0 : (A - O).dis() < (B - O).dis();
}
inline int convex(P *A, int len){
//求点集 A 的凸包并返回凸包大小
sort(A + 1, A + len + 1, cmp1); O = A[1];
sort(A + 2, A + len + 1, cmp2);
int top = 1; st[top] = A[1];
for(int i = 2; i <= len; i++){
while(top > 1 && (st[top] - st[top-1]) * (A[i] - st[top-1]) <= 0) top--;
st[++top] = A[i];
}
for(int i = 1; i <= top; i++) A[i] = st[i];
return top;
}
inline int inconvex(P x, P *A, int len){
//判断点 x 是否在大小为len的凸包 A 里,二分找到向量所在的三角区域
O = A[1];
if((x - O) * (A[2] - O) > 0 || (x - O) * (A[len] - O) < 0) return 0;
int pos = lower_bound(A + 2, A + len + 1, x, cmp2) - A - 1;
return (x - A[pos]) * (A[pos%len+1] - A[pos]) <= 0; }
inline int Minkowski(P *A, P *B, P *C, int n, int m){
//将大小为 n, m 的凸包 A, B 的闵可夫斯基和存在 C 中,并返回凸包大小
int tot1 = 0, tot2 = 0;
for(int i = 1; i < n; i++) s1[++tot1] = A[i+1] - A[i];
s1[++tot1] = A[1] - A[n];
for(int i = 1; i < m; i++) s2[++tot2] = B[i+1] - B[i];
s2[++tot2] = B[1] - B[m];
int p1 = 1, p2 = 1, tot = 1; C[tot] = A[1] + B[1];
for(; p1 <= n && p2 <= m; tot++)
C[tot+1] = C[tot] + (s1[p1] * s2[p2] >= 0 ? s1[p1++] : s2[p2++]);
for(; p1 <= n; p1++, tot++) C[tot+1] = C[tot] + s1[p1];
for(; p2 <= m; p2++, tot++) C[tot+1] = C[tot] + s2[p2];
return tot = convex(C, tot);
}
int main(){
read(n), read(m), read(q);
for(int i = 1; i <= n; i++) read(A[i].x), read(A[i].y);
n = convex(A, n);
for(int i = 1; i <= m; i++)
read(B[i].x), read(B[i].y), B[i].x = -B[i].x, B[i].y = -B[i].y;
m = convex(B, m);
int len = Minkowski(A, B, C, n, m);
while(q--){
ll x, y; read(x), read(y);
printf("%d\n", inconvex((P){x, y}, C, len));
}
return 0;
}

「JSOI2018」战争的更多相关文章

  1. 【LOJ】#2549. 「JSOI2018」战争

    题解 仔细分析了一下,如果写个凸包+每次暴力半平面交可以得到70分,正解有点懵啊 然后用到了一个非常结论,但是大概出题人觉得江苏神仙一个个都可以手证的结论吧.. Minkowski sum 两个凸包分 ...

  2. 「JLOI2015」战争调度 解题报告

    「JLOI2015」战争调度 感觉一到晚上大脑就宕机了... 题目本身不难,就算没接触过想想也是可以想到的 这个满二叉树的深度很浅啊,每个点只会和它的\(n-1\)个祖先匹配啊 于是可以暴力枚举祖先链 ...

  3. 「JLOI2015」战争调度

    题目 [内存限制:256 MiB][时间限制:1000 ms] [标准输入输出][题目类型:传统][评测方式:文本比较] 题目描述 脸哥最近来到了一个神奇的王国,王国里的公民每个公民有两个下属或者没有 ...

  4. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  5. LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流

    题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...

  6. LOJ 2551 「JSOI2018」列队——主席树+二分

    题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...

  7. LOJ 2547 「JSOI2018」防御网络——思路+环DP

    题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...

  8. LOJ #2547 Luogu P4517「JSOI2018」防御网络

    好像也没那么难写 LOJ #2547 Luogu P4517 题意 在一棵点仙人掌中等概率选择一个点集 求选出点集的斯坦纳树大小的期望 定义点仙人掌为不存在一个点在多个简单环中的连通图 斯坦纳树为在原 ...

  9. LOJ 2546 「JSOI2018」潜入行动——树形DP

    题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...

随机推荐

  1. 防止 Google Smart Lock 记忆错的用户名

    默认 chrome 会查找密码上面的那个(非隐藏非禁用)的表单域 如果上面是个短信验证码框,就会将验证码当成用户名提示用户保存. 在用户名 input 上添加 autocomplete="u ...

  2. Struts2笔记3--获取ServletAPI和OGNL与值栈

    获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.getConte ...

  3. sru源码--language model

    import sys import os import argparse import time import random import math import numpy as np import ...

  4. Once you eliminate all the other factors,the only thing remaining must be the truth.

    Once you eliminate all the other factors,the only thing remaining must be the truth. 一旦你排除了杂因,剩下的一定是 ...

  5. Gh0st配置加密与解密算法(异或、Base64)

    1.前言 分析木马程序常常遇到很多配置信息被加密的情况,虽然现在都不直接分析而是通过Wireshark之类的直接读记录. 2017年Gh0st样本大量新增,通过对木马源码的分析还发现有利用Gh0st加 ...

  6. 嵌入式Linux截图工具gsnap移植与分析【转】

    转自:http://blog.csdn.net/lu_embedded/article/details/53934184 版权声明:开心源自分享,快乐源于生活 —— 分享技术,传递快乐.转载文章请注明 ...

  7. Runtime - 消息发送原理

    Runtime - 消息发送原理. Objective-C运行时的核心就在于消息分派器objc_msgSend,消息分派器把选择器映射为函数指针,并调用被引用的函数. 要想理解objc_msgSend ...

  8. linux终端操作快捷键

    终端操作快捷键: 新建家目录下终端窗口:Ctrl+Alt+t在当期当前路径下新建终端窗口:Ctrl+Shift+n退出终端窗口:Ctrl+Shift+q 多个终端窗口之间相互切换:Tab+Alt 终端 ...

  9. 开发者常用的 Sublime Text 3 插件

    1.官网下载 Sublime Text 3 (已有安装包的,请忽略) Sublime Text 官网下载地址 : http://www.sublimetext.com/ 2.打开 Sublime Te ...

  10. ROSCon 2017通知 Announcing ROSCon 2017: September 21st and 22nd in Vancouver

    ROSCon 2017通知:9月21日和22日在温哥华 我们很高兴地宣布,2017年ROSCon将在举行9月21-22日,2017年温哥华会议中心在加拿大温哥华.2017年IROS将在同一地点9月24 ...