【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. jmeter压测

    一般压测时间:10-15分钟   这些并发用户一直在请求. 稳定性测试:一周  2天 衡量性能好坏的指标: tps 服务端每秒钟能处理的请求数 rt响应时间 就是你从发出请求到服务器端返回所需的时间. ...

  2. Ubuntu Linux Recovery Mode

    在安全模式/修復模式有以下的選項︰resume Resume normal boot繼續正常啟動作業,供不小心誤入此選單的使用者開機使用.(继续以正常模式启动) clean Try to make f ...

  3. node错误中间件处理 express类 带有路由操作

    let express = require('express'); let app = new express(); let bodyParser = require('body-parser'); ...

  4. React-Native之轮播组件looped-carousel的介绍与使用

    React-Native之轮播组件looped-carousel的介绍与使用 一,关于react-native轮播组件的介绍与对比 1,react-native-swiper在动态使用网页图片,多张图 ...

  5. 对B+树,B树,红黑树的理解

    出处:https://www.jianshu.com/p/86a1fd2d7406 写在前面,好像不同的教材对b树,b-树的定义不一样.我就不纠结这个到底是叫b-树还是b-树了. 如图所示,区别有以下 ...

  6. [转帖]Windows批处理(cmd/bat)常用命令小结

    Windows批处理(cmd/bat)常用命令小结 非常值得学习的文档 先放这里 有时间做实验, 转载自:“趣IT”微信公共号 前言 批处理文件(batch file)包含一系列 DOS命令,通常用于 ...

  7. [学习]UX 测试 5S 范围

    最近被UX测试搞的死去活来的 郁闷坏了. 豆瓣上面有一个介绍: 好的框架总是简洁的. Strategy - Scope - Structure - Skeleton - Surface五个层面,用bo ...

  8. C# Note26: [MethodImpl(MethodImplOptions.Synchronized)]与lock机制

    在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是最为常用的.如果仅仅是基于方法级别的线程同步,使用System.Runtime.CompilerServ ...

  9. C# Note25: .Net Core

    .NET Core全面扫盲贴 .NET Core与.NET Framework.Mono之间的关系 https://www.postgresql.org/

  10. docker 操作镜像的基本操作

    以安装mysql为例 1.拉取镜像 docker pull mysql 错误的启动 [root@localhost ~]# docker run --name mysql01 -d mysql 42f ...