题目

按逆时针顺序给出三个凸包点集 \(\mathbb{A,B,C}\),每次查询给出点 \(D\),

问是否存在点 \(A\in\mathbb{A},B\in\mathbb{B},C\in\mathbb{C}\) 满足 \(D\) 为 \(\Delta{ABC}\) 的重心。


分析

考虑重心的坐标就是 \((\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})\)

那么如果将 \(D\) 的坐标扩大三倍,那么也就是问 \(\mathbb{A,B,C}\) 三个凸包按照坐标分别相加组装成一个新的凸包,点 \(D\) 是否在这个凸包中。

可以发现三个凸包可以直接利用闵可夫斯基和合并起来,然后判断点是否位于多边形内部即可


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=150011;
typedef long long lll; int n,m,_n;
struct Point{
lll x,y;
inline Point operator -(const Point &t)const{
return (Point){x-t.x,y-t.y};
}
inline Point operator +(const Point &t)const{
return (Point){x+t.x,y+t.y};
}
}a[3][N],_a[N],b[N],B,seg[2][N];
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline lll Dis(Point x){return x.x*x.x+x.y*x.y;}
inline lll cj(Point x,Point y){return x.x*y.y-x.y*y.x;}
inline lll dj(Point x,Point y){return x.x*y.x+x.y*y.y;}
bool cmp(Point x,Point y){
rr lll t=cj(x-B,y-B);
return t>0||(!t&&Dis(x-B)<Dis(y-B));
}
inline bool within(Point p){
rr Point _p=p-a[2][1];
if (cj(_p,_a[2])>0||cj(_p,_a[_n])<0) return 0;
rr int l=2,r=_n-1;
while (l<=r){
rr int mid=(l+r)>>1;
if (cj(_p,_a[mid])<=0&&cj(_p,_a[mid+1])>=0)
return cj(_a[mid+1]-_p,_a[mid]-_p)<=0;
else if (cj(_p,_a[mid])>0) r=mid-1;
else l=mid+1;
}
return 0;
}
inline void Convex(Point *a,int &n){
rr int o=1,Top;
for (rr int i=2;i<=n;++i)
if (a[i].x<a[o].x||(a[i].x==a[o].x&&a[i].y<a[o].y)) o=i;
swap(a[o],a[1]),B=a[1],sort(a+2,a+1+n,cmp);
b[Top=1]=a[1];
for (rr int i=2;i<=n;++i){
while (Top>1&&cj(a[i]-b[Top-1],b[Top]-b[Top-1])>=0) --Top;
b[++Top]=a[i];
}
for (rr int i=1;i<=n;++i) a[i]=a[0]; n=Top;
for (rr int i=1;i<=Top;++i) a[i]=b[i],b[i]=a[0];
}
inline void Minkowski(){
for (rr int i=1;i<n;++i) seg[0][i]=a[0][i+1]-a[0][i]; seg[0][n]=a[0][1]-a[0][n];
for (rr int i=1;i<m;++i) seg[1][i]=a[1][i+1]-a[1][i]; seg[1][m]=a[1][1]-a[1][m];
rr int I=1,J=1;
a[2][_n=1]=a[0][1]+a[1][1];
for (;I<=n&&J<=m;++_n)
if (cj(seg[0][I],seg[1][J])>=0)
a[2][_n+1]=a[2][_n]+seg[0][I++];
else a[2][_n+1]=a[2][_n]+seg[1][J++];
for (;I<=n;++_n) a[2][_n+1]=a[2][_n]+seg[0][I++];
for (;J<=m;++_n) a[2][_n+1]=a[2][_n]+seg[1][J++];
}
signed main(){
n=iut(); for (rr int i=1;i<=n;++i) a[0][i]=(Point){iut(),iut()};
m=iut(); for (rr int i=1;i<=m;++i) a[1][i]=(Point){iut(),iut()};
Convex(a[0],n),Convex(a[1],m),Minkowski(),Convex(a[2],_n),n=_n,m=iut();
for (rr int i=1;i<=n;++i) a[0][i]=a[2][i];
for (rr int i=1;i<=m;++i) a[1][i]=(Point){iut(),iut()};
Convex(a[1],m),Minkowski(),Convex(a[2],_n);
for (rr int i=2;i<=_n;++i) _a[i]=a[2][i]-a[2][1];
for (rr int Q=iut();Q;--Q)
puts(within((Point){3*iut(),3*iut()})?"YES":"NO");
return 0;
}

#凸包,闵可夫斯基和#CF87E Mogohu-Rea Idol的更多相关文章

  1. 「题解」300iq Contest 2 H. Honorable Mention

    本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目链接:gym102331H. 题意概述 给定一个长度为 \(n\) 的序列 \(a\),有 \(q\) 次询问,每次询问给定三个 ...

  2. 5.8 NOI 模拟

    \(T1\) 比较容易想到的 二分转化为判定,判定是否存在一个子图能保证能一直在\(x\)时间内到达\(n\) 设\(dis(u,v)\)表示\(u->v\)的最短路 先找出候选节点\(i,di ...

  3. 洛谷CF1071E Rain Protection(计算几何,闵可夫斯基和,凸包,二分答案)

    洛谷题目传送门 CF题目传送门 对于这题,我无力吐槽. 虽然式子还是不难想,做法也随便口胡,但是一些鬼畜边界情况就是判不对. 首先显然二分答案. 对于每一个雨滴,它出现的时刻我们的绳子必须落在它上面. ...

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

    [BZOJ5317][JSOI2018]部落战争(凸包,闵可夫斯基和) 题面 BZOJ 洛谷 题解 很明显我们只需要两个凸包\(A,B\). 假设询问给定的方向向量是\(v\). 那么现在就是判断\( ...

  5. BZOJ2564: 集合的面积(闵可夫斯基和 凸包)

    题意 题目链接 Sol 这个东西的学名应该叫"闵可夫斯基和".就是合并两个凸包 首先我们先分别求出给出的两个多边形的凸包.合并的时候直接拿个双指针扫一下,每次选最凸的点就行了. 复 ...

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

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

  7. bzoj2564: 集合的面积(闵可夫斯基和 凸包)

    题面 传送门 题解 花了一个下午的时间调出了一个稍微能看的板子--没办法网上的板子和咱的不太兼容-- 首先有一个叫做闵可夫斯基和的东西,就是给你两个点集\(A,B\),要你求一个点集\(C=\{x+y ...

  8. [模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

    一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算 自适应Simpson Simpson's Rule: \[ \int ^b_a f(x)dx\approx ...

  9. 闵可夫斯基和(Mincowsky sum)

    一.概述 官方定义:两个图形A,B的闵可夫斯基和C={a+b|a∈A,b∈B}通俗一点:从原点向图形A内部的每一个点做向量,将图形B沿每个向量移动,所有的最终位置的并便是闵可夫斯基和(具有交换律) 例 ...

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

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

随机推荐

  1. 混合类Mixins介绍

    介绍 混合类是封装了一些通用行为的基类,旨在重用代码.通常,混合类本身并没有什么用,仅扩展这种类也行不通 因为在大多数情况下,它都依赖于其它类中定义的方法和属性.通过多继承,可将混合类与其它类一起使用 ...

  2. 【Azure 应用服务】应用代码中需要使用客户端证书访问服务接口,部署在应用服务后报错不能找到证书(Cannot find the X.509 certificate)

    问题描述 在应用中,需要访问另一个服务接口,这个接口需要使用客户端证书进行认证.在代码中使用 System.Security.Cryptography.X509Certificates 加载Windo ...

  3. Java this关键字使用 详解+ 证明

    1 package com.bytezero.thistest; 2 /** 3 * 4 * @Description 5 * @author Bytezero·zhenglei! Email:420 ...

  4. 用java实现书城项目(简单增删改查2)

    书城项目 登录 dao 接口:UserDao Users login(String username,String password); 实现:UserDaoImpl QueryRunner quer ...

  5. [VueJsDev] 快速入门 - vscode 自动格式化

    [VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html vscode 自动格式化(vue) ::: details ...

  6. puppeteer 提交 gitee - win10 (放弃,改成手点)async.series

    puppeteer 提交 gitee 需求 不想每次都登录到gitee上点击发布,想自动点击. 用puppeteer 模拟下 现在是win10环境,安装比较费尽 npm i puppeteer 这里用 ...

  7. MK5 机械键盘 说明书

    FN + 右箭头 就是加快节奏 FN + ScrLk 就是切换模式

  8. shell脚本中常用的自定义函数

    在Shell脚本中,你可以定义各种函数来执行不同的任务.以下是20个常用的自定义函数示例,涵盖了从文件操作.文本处理到系统监控等多个方面: 检查文件是否存在 file_exists() { [ -f ...

  9. python 读取串口数据常用函数及实例分析

    前记: 人生苦短,我用python,python在做一些算法验证和接口验证方面,的确是非常的好用.读取串口经常用到,这里就做个总结,给自己和周围的人做个备忘吧. 函数解析: 初始化串口数据: impo ...

  10. Mysql查询数据量大小

    --按实例 SELECT CONCAT(round(sum(DATA_LENGTH/1024/1024/1024),2),"GB") as datazise FROM inform ...