「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. 【Loadrunner】LR参数化:利用mysql数据库里面的数据进行参数化

    很多同学都在自学loadrunner去做压力测试,但是如果要利用LR做压力测试,或者是其他工具,其中有一个环节是我们避开不了的,比如说:参数化 今天华华就给大家简要的介绍下,如果你要做的参数化的数据来 ...

  2. Spring4笔记7--AspectJ 对 AOP 的实现

    AspectJ 对 AOP 的实现: 对于 AOP 这种编程思想,很多框架都进行了实现.Spring 就是其中之一,可以完成面向切面编程.然而,AspectJ 也实现了 AOP 的功能,且其实现方式更 ...

  3. SQL 存储过程分页

    CREATE PROC p_Team_GetTemaList @pageindex INT , @pagesize INT , @keywords VARCHAR(200) , --模糊查询 名称 标 ...

  4. 170406回顾-SQL Server的smalldatetime类型比较

    在比较SQL Server的类型为smalldatetime字段时出现下面的错误:将 expression 转换为数据类型 smalldatetime 时出现算术溢出错误 正确的比较方法如下:将lon ...

  5. node项目中用到的一些模块

    1.http模块,用来搭建服务器 代码,简单服务器实现 var http = require('http'); http.createServer(function (request, respons ...

  6. Java线程:新特征-有返回值的线程《转》

      原始文章   在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.   现在Java终于有可返回值的任务(也可以叫做线程)了. ...

  7. AdvStringGrid 复选框、goRowSelect

    var I: Integer; begin do begin AdvStringGrid1.AddCheckBox(, I, True, True); AdvStringGrid1.Cells[,I] ...

  8. GreenPlum学习笔记:create or replace function创建函数

    原始表数据如下: 需求:现要求按分号“;”将rate_item列进行分割后插入到新的数据表中. CREATE OR REPLACE FUNCTION fun_gp_test_xxx_20181026( ...

  9. mdb数据库文件如何导入Microsoft SQL Server 2008中

    1.在‘开始’菜单打开‘Microsoft SQL Server 2008→SQL Server Management Studio’. 2.新建一个数据库(名称自定义),选择新建的数据库点击右键选择 ...

  10. 最大子段和(Max Sum)

    Max Sum. The following is an instance. a)    (-2,11,-4,13,-5,-2) 思路: 最大子段和:给定一个序列(元素可正可负),找出其子序列中元素和 ...