令 \(a\in A,b\in B\) 则移动向量 \(\omega\) 使得存在 \(b+\omega=a\)

那么 \(\omega\) 需要满足 \(\omega=a−b\)

黑科技:闵可夫斯基和

直接构造闵可夫斯基和 \(C={a+(−b)}\)

余下问题便是判断输入的移动向量是否在 \(C\) 内

可以强行使凸包的最下面为 \((0,0)\),这样只要找到与坐标轴夹角最接近的边就好了

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn(2e5 + 5);
const double eps(1e-13);
const double pi(acos(-1));
const double inf(1e15); struct Point2D {
double x, y; inline Point2D(double _x = 0, double _y = 0) {
x = _x, y = _y;
} inline Point2D operator +(Point2D ad) const {
return Point2D(x + ad.x, y + ad.y);
} inline Point2D operator -(Point2D ad) const {
return Point2D(x - ad.x, y - ad.y);
} inline double operator ^(Point2D ad) const { //dot
return x * ad.x + y * ad.y;
} inline double operator *(Point2D ad) const { //cross
return x * ad.y - y * ad.x;
} inline Point2D operator *(double ad) const {
return Point2D(x * ad, y * ad);
} inline double Len() {
return sqrt(x * x + y * y);
} inline double Angle() {
return atan2(y, x);
}
}; struct Segment2D {
Point2D x, y; inline Segment2D(Point2D _x = Point2D(0, 0), Point2D _y = Point2D(0, 0)) {
x = _x, y = _y;
}
}; inline Point2D CrossPoint2D(Segment2D a, Segment2D b) {
double k1, k2, t;
k1 = (b.y - a.x) * (a.y - a.x);
k2 = (a.y - a.x) * (b.x - a.x);
t = k2 / (k1 + k2);
return b.x + (b.y - b.x) * t;
} Point2D tmp[maxn]; inline int Cmp(Point2D x, Point2D y) {
return (x - tmp[1]) * (y - tmp[1]) > 0;
} inline void Graham(Point2D *a, int &len) {
int l = 0, mn = 0, i;
for (i = 1; i <= len; ++i)
if (!mn || (a[i].x < a[mn].x || (a[i].x == a[mn].x && a[i].y < a[mn].y))) mn = i;
swap(a[1], a[mn]), tmp[l = 1] = a[1], sort(a + 2, a + len + 1, Cmp);
for (i = 2; i <= len; ++i) {
while (l > 1 && (a[i] - tmp[l - 1]) * (tmp[l] - tmp[l - 1]) >= 0) --l;
tmp[++l] = a[i];
}
for (i = 1; i <= l; ++i) a[i] = tmp[i];
len = l;
} int n, m, q, len;
Point2D a[maxn], b[maxn], c[maxn], p; inline void Minkowski() {
int i, j;
c[len = 1] = a[1] + b[1], a[0] = a[1], b[0] = b[1];
for (i = 1; i < n; ++i) a[i] = a[i + 1] - a[i];
for (i = 1; i < m; ++i) b[i] = b[i + 1] - b[i];
a[n] = a[0] - a[n], b[m] = b[0] - b[m];
for (i = j = 1; i <= n || j <= m; )
if (j > m || (i <= n && a[i] * b[j] >= 0)) ++len, c[len] = c[len - 1] + a[i++];
else ++len, c[len] = c[len - 1] + b[j++];
} inline int Query() {
int l, r, mid, cur = 2;
p = p - c[1];
if (c[len] * p > 0 || p * c[2] > 0) return 0;
l = 2, r = len - 1;
while (l <= r) {
mid = (l + r) >> 1;
if (c[mid] * p > 0) l = mid + 1, cur = mid;
else r = mid - 1;
}
return (p - c[cur]) * (c[cur + 1] - c[cur]) <= 0;
} int main() {
int i;
scanf("%d%d%d", &n, &m, &q);
for (i = 1; i <= n; ++i) scanf("%lf%lf", &a[i].x, &a[i].y);
for (i = 1; i <= m; ++i) scanf("%lf%lf", &b[i].x, &b[i].y), b[i] = b[i] * -1;
Graham(a, n), Graham(b, m), Minkowski(), Graham(c, len);
for (i = 2; i <= len; ++i) c[i] = c[i] - c[1];
for (i = 1; i <= q; ++i) scanf("%lf%lf", &p.x, &p.y), printf("%d\n", Query());
return 0;
}

BZOJ5317:[JSOI2018]战争(闵可夫斯基和)的更多相关文章

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

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

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

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

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

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

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

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

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

  6. P4557 [JSOI2018]战争

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

  7. [JSOI2018]战争

    题目描述 九条可怜是一个热爱读书的女孩子. 在她最近正在读的一本小说中,描述了两个敌对部落之间的故事.第一个部落有 nnn 个人,第二个部落有 mmm 个人,每一个人的位置可以抽象成二维平面上坐标为 ...

  8. 【LuoguP4557】[JSOI2018]战争

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

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

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

随机推荐

  1. 记录php漏洞--宇宙最强语言 PHP 爆出 DoS 漏洞,可以直接灌满 CPU

    站长之家(Chinaz.com)5月20日消息  近日,PHP被爆出存在远程DOS漏洞,若黑客利用该漏洞构造PoC发起连接,容易导致目标主机CPU被迅速消耗.此漏洞涉及众多PHP版本,因而影响范围极大 ...

  2. [Python] 模拟登录网站(。。为了之后操作数据。。)

    我司的内部管理(Web)系统(日报)着实..(mafan).. 所以,就想自己动手增加一下便利性. 计划是, - 桌面程序 用来方便记录(按自己格式,数据随时保存到sqlite中,备用) 通过一览来确 ...

  3. jmeter报错

    1.检测服务性能是报超时时问题 解决:因为服务器限制只能域名访问不能用ip+端口访问,但是jmter使用的是IP+端口访问 如图: 所以需要服务器放开这个端口,改成可以使用这个IP+端口访问

  4. 解决chrome无法启用印象笔记-剪藏功能

        新版Chrome浏览器安全的问题,导致从印象笔记官网下载的rxs(crx)文件无法直接通过drap&drop功能添加功能块.可以将rxs(crx)文件后缀名改成rar格式,然后解压,通 ...

  5. iOS 关于布局问题的一些认识

    ///更新约束和布局 更新约束布局相关的API - (void)updateConstraintsIfNeeded  调用此方法,如果有标记为需要重新布局的约束,则立即进行重新布局,内部会调用upda ...

  6. 【CODECHEF】Children Trips 倍增

    此题绝了,$O(n^{1.5}\ log\ n)$都可以过掉.... 题目大意:给你一颗$n$个点的树,每条边边权不是2就是$1$,有$m$个询问,每次询问一个人从$x$点走到$y$点,每天可以走的里 ...

  7. OS之内存管理 ---基本的内存管理策略(一)

    基本概念 基本硬件 CPU可以直接访问的通用存储只有内存和处理器的内置的寄存器.机器指令可以用内存地址作为参数,而不能用磁盘地址作为参数.所以执行指令以及指令使用的数据,应在这些可执行访问的存储设备上 ...

  8. Vue-Router路由Vue-CLI脚手架和模块化开发 之 使用props替代路由对象的方式获取参数

    在上一章博文中使用路由对象$route获取参数时,组件和路由对象耦合,在这篇博文中就可以使用props来进行解耦: 1.在组件中使用props选项定义数据,接收参数: 2.在路由中,使用props选项 ...

  9. Java之IO(八)PipedIutputStream和PipedOutputStream

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7056278.html 1.前言 本章介绍Java的IO体系中最后一对字节流--管道流.之前在字节数组流的时候就说 ...

  10. Pycharm常用快捷键,以及设置

    工欲善其事必先利其器,Python开发利器Pycharm常用快捷键以及配置如下,相信有了这些快捷键,你的开发会事半功倍 一 常用快捷键 编辑类: Ctrl + D             复制选定的区 ...