BZOJ5317:[JSOI2018]战争(闵可夫斯基和)
令 \(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]战争(闵可夫斯基和)的更多相关文章
- [BZOJ5317][JSOI2018]部落战争(闵可夫斯基和)
对于点集$A$,$B$,闵可夫斯基和$C=\{(x1+x2,y1+y2)|(x1,x2)\in A,(y1,y2)\in B\}$.由此可知,对于两个凸包$A$,$B$的闵可夫斯基和$C$满足,$C$ ...
- BZOJ5317 JSOI2018部落战争(凸包)
即询问凸包是否有交.这显然可以直接求半平面交,但是复杂度O(q(n+m)),且没有什么优化空间. 更直接地表示,即相当于询问是否存在点a∈A,b∈B,使得a+d=b.移项,得到d=b-a.可以发现等式 ...
- 洛谷P4557 [JSOI2018]战争(闵可夫斯基和+凸包)
题面 传送门 题解 看出这是个闵可夫斯基和了然而我当初因为见到这词汇是在\(shadowice\)巨巨的\(Ynoi\)题解里所以压根没敢学-- 首先您需要知道这个 首先如果有一个向量\(w\)使得\ ...
- [JSOI2018]战争(闵可夫斯基和)
害怕,可怜几何题 果然不会 题目就是说给你两个凸包,每次询问给你一个向量 \(c\) 问你能不能从两个凸包 \(A\) , \(B\) 里分别找到一个点 \(a\) , \(b\) 满足 \(a+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 ...
- P4557 [JSOI2018]战争
首先可以题目描述的两个点集是两个凸包,分别设为A和B. 考虑一个向量w不合法的条件. 即存在b+w=a,其中a属于A,b属于B. 也就是a-b=w. 即对b取反后和a的闵可夫斯基和. 求出闵可夫斯基和 ...
- [JSOI2018]战争
题目描述 九条可怜是一个热爱读书的女孩子. 在她最近正在读的一本小说中,描述了两个敌对部落之间的故事.第一个部落有 nnn 个人,第二个部落有 mmm 个人,每一个人的位置可以抽象成二维平面上坐标为 ...
- 【LuoguP4557】[JSOI2018]战争
题目链接 题意 给你两个点集. q次询问 , 每次把其中一个点集往一个方向移动 , 问两个点集的凸包还有没有交. Sol 闵可夫斯基和板子题. 把问题做如下转换: 我们本来两个凸包相交是相当于是对于移 ...
- 计算几何细节梳理&模板
点击%XZY巨佬 向量的板子 #include<bits/stdc++.h> #define I inline using namespace std; typedef double DB ...
随机推荐
- Spring Boot快速搭建Web工程
先想一下,正常我们想要创建一个web服务,首先需要下载tomcat,创建web工程,配置各种web.xml,引入spring的配置,各种配置文件一顿倒腾.....下载有了spring boot,你创建 ...
- Spark MLlib中的OneHot哑变量实践
在机器学习中,线性回归和逻辑回归算是最基础入门的算法,很多书籍都把他们作为第一个入门算法进行介绍.除了本身的公式之外,逻辑回归和线性回归还有一些必须要了解的内容.一个很常用的知识点就是虚拟变量(也叫做 ...
- vue的无缝滚动插件vue-seamless-scroll的安装与使用
npm安装地址 https://www.npmjs.com/package/vue-seamless-scroll 命令行执行: npm install vue-seamless-scroll --s ...
- (转)MySQL备份原理详解
MySQL备份原理详解 原文:http://www.cnblogs.com/cchust/p/5452557.html 备份是数据安全的最后一道防线,对于任何数据丢失的场景,备份虽然不一定能恢复百分之 ...
- Intellij-怎么避免import.*包,以及import包顺序问题
Intellij版本 IntelliJ IDEA 2018.1.2 (Ultimate Edition) Build #IU-181.4668.68, built on April 24, 2018 ...
- Camtasia Studio的下载
不多说,直接上干货! 具体还没写 https://www.techsmith.com/video-editor.html 欢迎大家,加入我的微信公众号:大数据躺过的坑 人工智能躺过的坑 ...
- Nodejs学习笔记(十四)—Mongoose介绍和入门
简介 Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具 那么要使用它,首先你得装上node.js和mongodb,关于mongodb的安装和操作介绍可以参考:ht ...
- weblogic:local class incompatible: stream classdesc serialVersionUID
问题:jdk版本不兼容 方法:修改weblogic对应的jdk版本
- java 实现 PDF 加水印功能
使用java代码实现给PDF加水印的功能 首先导入所需要的依赖 <dependency> <groupId>com.itextpdf</groupId> <a ...
- JS实现年月日三级联动+省市区三级联动+国家省市三级联动
开篇随笔:最近项目需要用到关于年月日三级联动以及省市区三级联动下拉选择的功能,于是乎网上搜了一些做法,觉得有一些只是给出了小的案例或者只有单纯的js还不完整,却很难找到详细的具体数据(baidu搜索都 ...