【BZOJ5317】[JSOI2018]部落战争(凸包,闵可夫斯基和)

题面

BZOJ

洛谷

题解

很明显我们只需要两个凸包\(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]部落战争(凸包,闵可夫斯基和)的更多相关文章

  1. BZOJ5317 JSOI2018部落战争(凸包)

    即询问凸包是否有交.这显然可以直接求半平面交,但是复杂度O(q(n+m)),且没有什么优化空间. 更直接地表示,即相当于询问是否存在点a∈A,b∈B,使得a+d=b.移项,得到d=b-a.可以发现等式 ...

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

    对于点集$A$,$B$,闵可夫斯基和$C=\{(x1+x2,y1+y2)|(x1,x2)\in A,(y1,y2)\in B\}$.由此可知,对于两个凸包$A$,$B$的闵可夫斯基和$C$满足,$C$ ...

  3. 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 ...

  4. BZOJ 5317: [Jsoi2018]部落战争

    传送门 写出式子,若存在 $a \in A$,$b \in B$,使得 $b+v=a$,那么此方案会产生冲突 即存在 $a \in A$,$b \in B$,使得 $v=a+(-b)$,设 $C=A+ ...

  5. 「JSOI2018」战争

    「JSOI2018」战争 解题思路 我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在 \[ b\in B,(b+w)\in A \] 这里 \(A, B\) 表示凸包内部 ...

  6. BZOJ2150: 部落战争

    题解: 把每个点拆成入点和出点,因为必须经过一次且只能经过一次.所以在两个点之间连一条上界=下界=1的边. 然后再s到每个入点连边,每个出点向t连边,点与点之间... 求最小流就可以过了... (感觉 ...

  7. BZOJ 2150: 部落战争 最大流

    2150: 部落战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...

  8. BZOJ-2150部落战争(最小路径覆盖)

    2150: 部落战争 Time Limit: 10 Sec  Memory Limit: 259 MB Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国 ...

  9. 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】

    P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...

随机推荐

  1. openstack-KVM-vCPU

    一.KVM基础功能 (1)支持 硬件支持 VT-x VT-d 系统支持 kernel > 3.5 (2)计算机系统的子系统 CPU 处理器 Memory 内存 Storage 存储 Networ ...

  2. 【kindle笔记】之 《活着》-2018-2-5

    [kindle笔记]读书记录-总 2018-2-5 今天凌晨一口气看完了<活着>,没想到竟然是个赤裸裸的悲剧,心情不太好地睡去. 福贵,一个小人物,坎坷无比的一生. 当你以为真他妈惨,真是 ...

  3. html,css学习实践总结

    网页的布局方式 1.什么是网页的布局方式? 网页的布局方式其实就是指浏览器是如何对网页中的元素进行排版的 1.标准流(文档流/普通流)排版方式 1.1其实浏览器默认的排版方式就是标准流的排版方式 1. ...

  4. javascript内置函数:toString()

    不同对象有不同的实现方式. 1.Number对象: 语法:numberObject.toString([radix]) 参数:radix,可选/Number类型,指定的基数(进制数),支持[2,36] ...

  5. 工作效率提升之Eclipse篇(1):干掉烦人的xml文件的validation

    每次启动maven项目,都会有一堆烦人的xml文件的validation,一旦网络较慢,项目重新启动的时候,这些多余的验证纯属浪费时间. Eclipse上取消validation的方法: 1.菜单[W ...

  6. Django的模板层

    一 模版简介 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now ...

  7. Appscanner实验还原code2

    import _pickle as pickle from sklearn import svm, ensemble import random from sklearn.metrics import ...

  8. python易混易乱(1)

    字典 基础操作 <1>keys my_dict = {"name":"zhangsan","age":18} res = my_ ...

  9. freemarker -include

    在ftl中使用<#include >时 ,页面被强制显示 需要在struts.xml增加跳转type ,或则可以加同一<result-types></result-typ ...

  10. ES 6 系列 - Proxy

    Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以是一种“元编程”,即对编程语言进行编程. 简单地理解,就是在目标对象之前假设一层“拦截”,外界对改对象的访问,都必须先通过这层拦截 ...