题目描述

九条可怜是一个热爱读书的女孩子。

在她最近正在读的一本小说中,描述了两个敌对部落之间的故事。第一个部落有 nnn 个人,第二个部落有 mmm 个人,每一个人的位置可以抽象成二维平面上坐标为 (xi,yi)(x_i,y_i)(xi​,yi​) 的点。

在这本书中,人们有很强的领地意识,对于平面上的任何一个点,如果它被三个来自同一部落的人形成的三角形(可能退化成一条线段)包含(包括边界),那么这一个点就属于这一个部落的领地。如果存在一个点同时在两个阵营的领地中,那么这两个部落就会为了争夺这一个点而发生战争。

常年的征战让两个部落不堪重负,因此第二个部落的族长作出了一个英明的决定,他打算选择一个向量 (dx,dy)(dx,dy)(dx,dy) ,让所有的族人都迁徙这个向量的距离,即所有第二阵营的人的坐标都变成 (xi+dx,yi+dy)(x_i+dx,y_i+dy)(xi​+dx,yi​+dy) 。

现在他计划了 qqq 个迁徙的备选方案,他想要你来帮忙对每一个迁徙方案,计算一下在完成了迁徙之后,两个部落之间还会不会因为争夺领地而发生战争。

输入格式

第一行输入三个整数 n,m,qn,m,qn,m,q,表示两个部落里的人数以及迁徙的备选方案数。

接下来 nnn 行每行两个整数 xi,yix_i,y_ixi​,yi​​​ 表示第一个部落里的人的坐标。

接下来 mmm 行每行两个整数 xi,yix_i,y_ixi​,yi​​​ 表示第二个部落里的人的坐标。

接下来 qqq 行每行两个整数 dxi,dyidx_i,dy_idxi​,dyi​​​ 表示一个迁徙方案。

输入数据保证所有人的坐标两两不同。

输出格式

对于每个迁徙方案,输出一行一个整数,000 表示不会发生冲突,111 表示会发生冲突。

输入输出样例

输入 #1

4 4 3
0 0
1 0
0 1
1 1
-1 0
0 3
0 2
0 -1
0 0
2 3
0 -1
输出 #1
1
0
设a,b为两个部落构成的凸包
b+d=a等价于d=a-b
即取反b,求出凸包,再用Minkowski和合并两凸包
查询用二分查询向量d所在区间,用叉积判断是否在凸包内
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lol;
struct Node
{
lol x,y;
Node operator + (const Node &b) const
{
return (Node){x+b.x,y+b.y};
}
Node operator - (const Node &b) const
{
return (Node){x-b.x,y-b.y};
}
}a[],b[],sa[],sb[],sta[],bs,s1[],s2[],s[];
int n,m,q,top;
bool cmp(Node a,Node b)
{
if (a.y==b.y) return a.x<b.x;
return a.y<b.y;
}
lol cross(Node a,Node b)
{
return (a.x*b.y-a.y*b.x);
}
lol dist(Node a)
{
return a.x*a.x+a.y*a.y;
}
bool cmp1(Node A,Node B)
{
lol t=cross((a[]-A),(a[]-B));
if (t==) return dist(a[]-A)<dist(a[]-B);
return t>;
}
bool cmp2(Node A,Node B)
{
lol t=cross((b[]-A),(b[]-B));
if (t==) return dist(b[]-A)<dist(b[]-B);
return t>;
}
int grahama(int N)
{int i;
sort(a+,a+N+,cmp);
sort(a+,a+N+,cmp1);
top=;
sa[++top]=a[];
if (N==) return ;
sa[++top]=a[];
for (i=;i<=N;i++)
{
while (top>&&cross(a[i]-sa[top-],sa[top]-sa[top-])>=) top--;
top++;
sa[top]=a[i];
}
sa[top+]=a[];
return top;
}
int grahamb(int N)
{int i;
sort(b+,b+N+,cmp);
sort(b+,b+N+,cmp2);
top=;
sb[++top]=b[];
if (N==) return ;
sb[++top]=b[];
for (i=;i<=N;i++)
{
while (top>&&cross(b[i]-sb[top-],sb[top]-sb[top-])>=) top--;
top++;
sb[top]=b[i];
}
sb[top+]=b[];
return top;
}
bool cmpp(Node A,Node B)
{
lol t=cross((s[]-A),(s[]-B));
if (t==) return dist(s[]-A)<dist(s[]-B);
return t>;
}
int grahams(int N)
{int i;
sort(s+,s+N+,cmp);
sort(s+,s+N+,cmpp);
top=;
sta[++top]=s[];
if (N==) return ;
sta[++top]=s[];
for (i=;i<=N;i++)
{
while (top>&&cross(s[i]-sta[top-],sta[top]-sta[top-])>=) top--;
top++;
sta[top]=s[i];
}
sta[top+]=s[];
return top;
}
bool cmp3(Node A,Node B)
{
return cross(A,B)>||(cross(A,B)==&&dist(A)<dist(B));
}
lol find(Node A)
{
if(cross(A,sta[])>||cross(sta[top],A)>) return ;
lol ps=lower_bound(sta+,sta+top+,A,cmp3)-sta-;
return cross((A-sta[ps]),(sta[ps%top+]-sta[ps]))<=;
}
void Minkowski()
{
for(lol i=;i<n;i++) s1[i]=sa[i+]-sa[i];s1[n]=sa[]-sa[n];
for(lol i=;i<m;i++) s2[i]=sb[i+]-sb[i];s2[m]=sb[]-sb[m];
top=;
s[top]=sa[]+sb[];
lol i=,j=;
while(i<=n&&j<=m) ++top,s[top]=s[top-]+(cross(s1[i],s2[j])>=?s1[i++]:s2[j++]);
while(i<=n) ++top,s[top]=s[top-]+s1[i++];
while(j<=m) ++top,s[top]=s[top-]+s2[j++];
}
int main()
{int i,j;
lol dx,dy;
cin>>n>>m>>q;
for (i=;i<=n;i++)
scanf("%lld%lld",&a[i].x,&a[i].y);
for (i=;i<=m;i++)
scanf("%lld%lld",&b[i].x,&b[i].y),b[i].x=-b[i].x,b[i].y=-b[i].y;
n=grahama(n);
m=grahamb(m);
Minkowski();
top=grahams(top);
bs=sta[];
for (i=;i<=top;i++)
sta[i]=sta[i]-bs; for (i=;i<=q;i++)
{
scanf("%lld%lld",&dx,&dy);
if (find((Node){dx,dy}-bs))
printf("1\n");
else printf("0\n");
}
}

[JSOI2018]战争的更多相关文章

  1. P4557 [JSOI2018]战争

    首先可以题目描述的两个点集是两个凸包,分别设为A和B. 考虑一个向量w不合法的条件. 即存在b+w=a,其中a属于A,b属于B. 也就是a-b=w. 即对b取反后和a的闵可夫斯基和. 求出闵可夫斯基和 ...

  2. BZOJ5317:[JSOI2018]战争(闵可夫斯基和)

    令 \(a\in A,b\in B\) 则移动向量 \(\omega\) 使得存在 \(b+\omega=a\) 那么 \(\omega\) 需要满足 \(\omega=a−b\) 黑科技:闵可夫斯基 ...

  3. 洛谷P4557 [JSOI2018]战争(闵可夫斯基和+凸包)

    题面 传送门 题解 看出这是个闵可夫斯基和了然而我当初因为见到这词汇是在\(shadowice\)巨巨的\(Ynoi\)题解里所以压根没敢学-- 首先您需要知道这个 首先如果有一个向量\(w\)使得\ ...

  4. [JSOI2018]战争(闵可夫斯基和)

    害怕,可怜几何题 果然不会 题目就是说给你两个凸包,每次询问给你一个向量 \(c\) 问你能不能从两个凸包 \(A\) , \(B\) 里分别找到一个点 \(a\) , \(b\) 满足 \(a+c= ...

  5. 【LuoguP4557】[JSOI2018]战争

    题目链接 题意 给你两个点集. q次询问 , 每次把其中一个点集往一个方向移动 , 问两个点集的凸包还有没有交. Sol 闵可夫斯基和板子题. 把问题做如下转换: 我们本来两个凸包相交是相当于是对于移 ...

  6. 计算几何细节梳理&模板

    点击%XZY巨佬 向量的板子 #include<bits/stdc++.h> #define I inline using namespace std; typedef double DB ...

  7. HHHOJ #151. 「NOI模拟 #2」Nagisa

    计算几何板子题(我才没有拷板子的说--) 众所周知,三角形的重心坐标是\((\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})\) 然后我们发现如果我们有一个点集 ...

  8. 【学习笔记】Minkowski和

    这还是个被我咕了N久的玩意 Minkowski和是一个奇怪的玩意 他长这样 $S={a+b \| a \in A , b \in B}$ AB可以是点集也可是向量集(显然) 他可以处理一些奇怪的东西 ...

  9. JSOI部分题解

    JSOI部分题解 JSOI2018 战争 问题转化为给定你两个凸包\(\mathbb S,\mathbb T\),每次独立的询问将\(\mathbb T\)中的每个点移动一个向量,问\(\mathbb ...

随机推荐

  1. LeetCode 82. 删除排序链表中的重复元素 II(Remove Duplicates from Sorted List II)

    82. 删除排序链表中的重复元素 II 82. Remove Duplicates from Sorted List II 题目描述 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中没有 ...

  2. Java开发笔记(一百三十四)Swing的基本对话框

    桌面程序在运行过程中,时常需要在主界面之上弹出小窗,把某种消息告知用户,以便用户及时知晓并对症处理.这类小窗口通常称作对话框,依据消息交互的过程,可将对话框分为三类:消息对话框.确认对话框.输入对话框 ...

  3. django中的media

    我们用Django写一个网站,可能会需要将用户注册时的头像展示到页面上,当然一开始学的用户上传头像文件都是在项目目录下的,那我们在网页上获取这个头像文件是获取不到的,此时我们需要配置一下media,才 ...

  4. day20——规范化目录

    day20 为什么要有规范化目录 可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等.从而非常快速的了解这个项目. 可维护性高: 定 ...

  5. HTML常用技巧

    1. 为网页链接添加快捷键:accesskey 属性 https://zhidao.baidu.com/question/2267343500557447508.html 2. 键盘事件设置快捷键:h ...

  6. mysql中sum与if,case when 结合使用

    1.sum与if结合使用 如图:数据表中,count_money 字段可为正,可为负.为正表示收入,负表示支出. 统计总收入,总支出. select sum(if(count_money > 0 ...

  7. javascript 同源策略和 JSONP 的工作原理

    同源策略 同源策略是一个约定,该约定阻止当前脚本获取或操作另一域的内容.同源是指:域名.协议.端口号都相同. 简单地说,A 服务器下的 a 端口执行 ajax 程序,不能获取 B 服务器或者 A 服务 ...

  8. YARN-HA高可用集群搭建

    YARN-HA配置 1. YARN-HA工作机制 1.1 官方文档:http://hadoop.apache.org/docs/r2.7.2/hadoop-yarn/hadoop-yarn-site/ ...

  9. UnityShader - 渲染管线

    定义: 显卡内部处理图像信号的并行处理单元,也称为渲染流水线 发生位置: CPU和GPU 渲染机理: 将图像所具备的图形信息(顶点.纹理.材质.摄像机位置等)经过一系列阶段的处理,最终转换为屏幕上的图 ...

  10. IDEA使用@Data注解,类调用get、set方法标红的解决办法

    1.在setting中,下载lombok插件,安装完成后重启idea