【BZOJ5317】[JSOI2018]部落战争(凸包,闵可夫斯基和)
【BZOJ5317】[JSOI2018]部落战争(凸包,闵可夫斯基和)
题面
题解
很明显我们只需要两个凸包\(A,B\)。
假设询问给定的方向向量是\(v\)。
那么现在就是判断\(B+v\)与\(A\)时候有交集。
转移一下改为判定向量\(v\)时候在\(A-B\)中,翻转\(B\)的坐标,做闵可夫斯基和得到\(A-B\)。
那么每次只需要判断向量\(v\)是否在凸包内即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MAX 100100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Point{ll x,y;double ang;};
bool operator<(Point a,Point b){return (a.ang!=b.ang)?a.ang<b.ang:a.x<b.x;}
Point operator+(Point a,Point b){return (Point){a.x+b.x,a.y+b.y};}
Point operator-(Point a,Point b){return (Point){a.x-b.x,a.y-b.y};}
Point operator*(Point a,ll b){return (Point){a.x*b,a.y*b};}
Point operator/(Point a,ll b){return (Point){a.x/b,a.y/b};}
ll operator*(Point a,Point b){return a.x*b.x+a.y*b.y;}
ll Cross(Point a,Point b){return a.x*b.y-a.y*b.x;}
ll Len(Point a){return a.x*a.x+a.y*a.y;}
ll Dis(Point a,Point b){return Len(a-b);}
struct Line{Point a,v;};
Point S[MAX<<1];int top;
void Graham(Point *p,int n)
{
int pos=1;top=0;
for(int i=2;i<=n;++i)
if(p[i].x<p[pos].x||(p[i].x==p[pos].x&&p[i].y<p[pos].y))
pos=i;
swap(p[1],p[pos]);
for(int i=2;i<=n;++i)p[i].ang=atan2(p[i].y-p[1].y,p[i].x-p[1].x);
sort(&p[2],&p[n+1]);S[++top]=p[1];S[++top]=p[2];
for(int i=3;i<=n;++i)
{
while(top>2&&Cross(p[i]-S[top],p[i]-S[top-1])>=0)--top;
S[++top]=p[i];
}
}
Point t1[MAX],t2[MAX];
void Minkowski(Point *p1,Point *p2,int n,int m)
{
p1[n+1]=p1[1];p2[m+1]=p2[1];
for(int i=1;i<=n;++i)t1[i]=p1[i+1]-p1[i];
for(int i=1;i<=m;++i)t2[i]=p2[i+1]-p2[i];
S[top=1]=p1[1]+p2[1];
int i=1,j=1;
while(i<=n&&j<=m)
{
++top;S[top]=S[top-1];
if(Cross(t1[i],t2[j])>=0)S[top]=S[top]+t1[i++];
else S[top]=S[top]+t2[j++];
}
while(i<=n)++top,S[top]=S[top-1]+t1[i++];
while(j<=m)++top,S[top]=S[top-1]+t2[j++];
}
int n,m,Q;
Point p1[MAX],p2[MAX],p[MAX],a,bs;
bool cmp(Point a,Point b){return Cross(a,b)>0||(Cross(a,b)==0&&Len(a)<Len(b));}
bool check(Point a)
{
if(Cross(a,p[1])>0||Cross(p[top],a)>0)return false;
int pos=lower_bound(&p[1],&p[top+1],a,cmp)-p-1;
return Cross(a-p[pos],p[pos%top+1]-p[pos])<=0;
}
int main()
{
n=read();m=read();Q=read();
for(int i=1;i<=n;++i)p1[i].x=read(),p1[i].y=read();
Graham(p1,n);for(int i=1;i<=top;++i)p1[i]=S[i];n=top;
for(int i=1;i<=m;++i)p2[i].x=-read(),p2[i].y=-read();
Graham(p2,m);for(int i=1;i<=top;++i)p2[i]=S[i];m=top;
Minkowski(p1,p2,n,m);top-=1;bs=S[1];
for(int i=1;i<=top;++i)p[i]=S[i]-bs;
while(Q--)
{
a.x=read(),a.y=read();
printf("%d\n",check(a-bs));
}
return 0;
}
【BZOJ5317】[JSOI2018]部落战争(凸包,闵可夫斯基和)的更多相关文章
- BZOJ5317 JSOI2018部落战争(凸包)
即询问凸包是否有交.这显然可以直接求半平面交,但是复杂度O(q(n+m)),且没有什么优化空间. 更直接地表示,即相当于询问是否存在点a∈A,b∈B,使得a+d=b.移项,得到d=b-a.可以发现等式 ...
- [BZOJ5317][JSOI2018]部落战争(闵可夫斯基和)
对于点集$A$,$B$,闵可夫斯基和$C=\{(x1+x2,y1+y2)|(x1,x2)\in A,(y1,y2)\in B\}$.由此可知,对于两个凸包$A$,$B$的闵可夫斯基和$C$满足,$C$ ...
- 2019.02.21 bzoj5317: [Jsoi2018]部落战争(凸包+Minkowski和)
传送门 题意:qqq次询问把一个凸包整体加一个向量(x,y)(x,y)(x,y)之后是否与另外一个凸包相交. 思路:转化一下发现只要会求A+B={v⃗=a⃗+b⃗∣a⃗∈A,b⃗∈B}A+B=\{\v ...
- BZOJ 5317: [Jsoi2018]部落战争
传送门 写出式子,若存在 $a \in A$,$b \in B$,使得 $b+v=a$,那么此方案会产生冲突 即存在 $a \in A$,$b \in B$,使得 $v=a+(-b)$,设 $C=A+ ...
- 「JSOI2018」战争
「JSOI2018」战争 解题思路 我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在 \[ b\in B,(b+w)\in A \] 这里 \(A, B\) 表示凸包内部 ...
- BZOJ2150: 部落战争
题解: 把每个点拆成入点和出点,因为必须经过一次且只能经过一次.所以在两个点之间连一条上界=下界=1的边. 然后再s到每个入点连边,每个出点向t连边,点与点之间... 求最小流就可以过了... (感觉 ...
- BZOJ 2150: 部落战争 最大流
2150: 部落战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...
- BZOJ-2150部落战争(最小路径覆盖)
2150: 部落战争 Time Limit: 10 Sec Memory Limit: 259 MB Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国 ...
- 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】
P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...
随机推荐
- Django之事务
Django之事务 事务就是将一组操作捆绑在一起,只有当这一组操作全部都成功以后这个事务才算成功;当这组操作中有任何一个没有操作成功,则这个操作就会回滚,回到操作之前的状态. 其中牵扯到向数据库中写数 ...
- JUnit的配置及使用
一.安装插件JUnitGenertor V2.0 File->Setting->Plugins->在搜索框里输入JUintGenerator V2.0 二.导入JUnit相关jar包 ...
- C\C++学习笔记 2
C++记录4 自动存储: 生命周期在代码块,存储在栈,后入先出. 静态存储: 存在于程序的整个周期. 动态存储: 使用new delete 在内存池(堆)存储,不受程序生命周期控制. 内存泄露: 没有 ...
- java不同的包下相同的类名的问题与解决办法
Java中的类以包进行分类组织,当程序中需要用到某个包下的类时,可以以该类的全限定名进行引用.这样,不同的包中的类就可以同名,不会产生混淆. 但是这样就可能导致引用的时候会产生一些问题. 第一个问题, ...
- AngularJS 中的 factory、 service 和 provider区别,简单易懂
转自:http://blog.csdn.net/ywl570717586/article/details/51306176 初学 AngularJS 时, 肯定会对其提供 factory . serv ...
- 关于对ProgressBar定义模板的一些总结
在之前的博客中曾经写到了一篇关于如何定义圆形进度条的文章,今天就ProgressBar再来进行一些总结,首先来介绍一下ProgressBar的结构,ProgressBar控件的模板有两个部分,我们在定 ...
- 莫烦sklearn学习自修第九天【过拟合问题处理】
1. 过拟合问题可以通过调整机器学习的参数来完成,比如sklearn中通过调节gamma参数,将训练损失和测试损失降到最低 2. 代码实现(显示gamma参数对训练损失和测试损失的影响) from _ ...
- Linux常见操作
前面的话 本文将详细介绍Linux常见操作 基本概念 Linux严格区分大小写,所有内容以文件形式保存,包括硬件 Linux没有扩展名的概念,不靠扩展名来区分文件类型.但有一些约定俗成的扩展名 压缩包 ...
- javascript中关于value的一个小知识点(value既是属性也是变量)
今天在学习input的value值时,发现这么一个小知识点,以前理解不太透彻 [1]以下这种情况是常见情况,会弹出“测试内容” <input type="button" va ...
- undefined reference to `cv::VideoCapture
出现opencv链接的问题原因: 1. 路径设置不正确,caffe会优先搜索Makefile.config里面的环境设置 2. anaconda2装的opencv和配置的opencv路径不一致 比如, ...