害怕,可怜几何题

果然不会

题目就是说给你两个凸包,每次询问给你一个向量 \(c\) 问你能不能从两个凸包 \(A\) , \(B\) 里分别找到一个点 \(a\) , \(b\) 满足 \(a+c=b\) 。

考虑怎样的向量可以满足。

发现只有让B中的每一个点-A中的每一个点的集合中的向量可以满足。因为把上面的式子化一下就是 \(c=b-a\) 。

凸包B中的点集减去凸包A中的点集。这不是闵可夫斯基和吗?

所以我们把两个凸包的闵可夫斯基和求出,然后每一个询问查看给的向量在不在闵可夫斯基和中即可。

代码极丑,不过我判向量是不是在凸包里是把凸包切成上下两个凸包,然后分类讨论求的。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define int long long
const int N=501000;
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int top1,top2,top;
struct node{
int x,y;
node (int xx=0,int yy=0){
x=xx,y=yy;
}
}stack1[N],stack2[N],a[N],b[N],ans[N],ans1[N];
node operator +(node a,node b){
return node(a.x+b.x,a.y+b.y);
}
node operator -(node a,node b){
return node(a.x-b.x,a.y-b.y);
}
bool cmp(node a,node b){
if(a.x==b.x)return a.y<b.y;
else return a.x<b.x;
}
int chaji(node a,node b){
return a.x*b.y-a.y*b.x;
}
bool judge(node a,node b,node c){
return chaji(b-c,a-b)<=0;
}
int n,m;
void tubao1(){
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
while(top1>1&&judge(a[i],stack1[top1],stack1[top1-1]))top1--;
stack1[++top1]=a[i];
}
int k=top1;
for(int i=n-1;i>=1;i--){
while(top1>k&&judge(a[i],stack1[top1],stack1[top1-1]))top1--;
stack1[++top1]=a[i];
}
top1--;
}
void tubao2(){
sort(b+1,b+1+m,cmp);
for(int i=1;i<=m;i++){
while(top2>1&&judge(b[i],stack2[top2],stack2[top2-1]))top2--;
stack2[++top2]=b[i];
}
int k=top2;
for(int i=m-1;i>=1;i--){
while(top2>k&&judge(b[i],stack2[top2],stack2[top2-1]))top2--;
stack2[++top2]=b[i];
}
top2--;
}
void sum(){
for(int i=1;i<=top1;i++)a[i]=stack1[i+1]-stack1[i];
for(int i=1;i<=top2;i++)b[i]=stack2[i+1]-stack2[i];
ans[top=1]=stack1[1]+stack2[1];
int now1=1,now2=1;
while(now1<=top1&&now2<=top2)top++,ans[top]=ans[top-1]+(chaji(a[now1],b[now2])>=0?a[now1++]:b[now2++]);
while(now1<=top1)top++,ans[top]=ans[top-1]+a[now1++];
while(now2<=top2)top++,ans[top]=ans[top-1]+b[now2++];
top--;
}
bool in(node x){
if(x.x<ans[1].x||x.x>ans[top1].x)return false;
if(x.x==ans[1].x){
if(x.y>=ans[1].y&&x.y<=ans1[1].y)return true;
else return false;
}
if(x.x==ans[top1].x){
if(x.y>=ans[top1].y&&x.y<=ans1[top2].y)return true;
else return false;
}
int A=lower_bound(ans+1,ans+1+top1,x,cmp)-ans;
int B=lower_bound(ans1+1,ans1+1+top2,x,cmp)-ans1;
if(chaji(ans1[B]-x,ans1[B-1]-x)>=0&&chaji(ans[A-1]-x,ans[A]-x)>=0)return true;
else return false;
}
int q;
signed main(){
n=read();m=read();q=read();
for(int i=1;i<=n;i++)a[i].x=read(),a[i].y=read();
tubao1();
for(int i=1;i<=m;i++)b[i].x=-read(),b[i].y=-read();
tubao2();
sum();
for(int i=1;i<=top;i++)
if(ans[i+1].x<ans[i].x){top1=i;break;}
for(int i=top1;i<=top+1;i++)
ans1[i-top1+1]=ans[i];
top2=top+1-top1+1;
while(ans[top1-1].x==ans[top1].x)top1--;
while(ans1[top2-1].x==ans1[top2].x)top2--;
for(int i=1;i<=top2/2ll;i++)swap(ans1[i],ans1[top2-i+1]);
while(q--){
int A=read(),B=read();
node x=node(A,B);
if(in(x))printf("1\n");
else printf("0\n");
}
return 0;
}

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

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

    令 \(a\in A,b\in B\) 则移动向量 \(\omega\) 使得存在 \(b+\omega=a\) 那么 \(\omega\) 需要满足 \(\omega=a−b\) 黑科技:闵可夫斯基 ...

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

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

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

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

  4. P4557 [JSOI2018]战争

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

  5. [JSOI2018]战争

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

  6. 【LuoguP4557】[JSOI2018]战争

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

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

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

  8. HHHOJ #151. 「NOI模拟 #2」Nagisa

    计算几何板子题(我才没有拷板子的说--) 众所周知,三角形的重心坐标是\((\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})\) 然后我们发现如果我们有一个点集 ...

  9. 【学习笔记】Minkowski和

    这还是个被我咕了N久的玩意 Minkowski和是一个奇怪的玩意 他长这样 $S={a+b \| a \in A , b \in B}$ AB可以是点集也可是向量集(显然) 他可以处理一些奇怪的东西 ...

随机推荐

  1. 执行计划中Using filesort,Using temporary相关语句的优化解决

    昨天听开发人员提到,相关的彩票网页当中一个页面刷新的很慢,特别是在提取数据的时候,今天早上一到,便去找开发人员要去相关的也没进行浏览,窥探哪些数据出现了问题,开发人员使用PHP开发,所以我用IE很容易 ...

  2. [bzoj1218][HNOI2003]激光炸弹_暴力

    激光炸弹 bzoj-1218 HNOI-2003 题目大意:在笛卡尔坐标系上有n个点,问一个平行于坐标轴的r*r的正方形可以最多覆盖多少个目标. 注释:$1\le n \le 10000$,$1\le ...

  3. Spring深入理解(一)

    Spring 框架的设计理念与设计模式分析 Spring核心组件 Spring 框架中的核心组件只有三个:Core.Context 和 Beans Spring 的设计理念 前面介绍了 Spring ...

  4. 关于Hanoi算法

    java经典算法——河内算法(Hanoi) 有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,要把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出 ...

  5. git分支合并概念

    git merge命令用于合并指定分支到当前分支. git merge命令用于合并指定分支到当前分支. git merge命令用于合并指定分支到当前分支. 创建与合并分支 阅读: 931277 在版本 ...

  6. 奇妙的go语言(基本的语法)

    [ 声明:版权全部,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 学习一门新的语言无非就是从主要的语法開始的.通过语法书来学习语言毕竟是很枯燥的,所以我们最好还 ...

  7. LDA 两种含义

    关于LDA有两种含义,一种是线性判别分析(Linear Discriminant Analysis),一种是概率主题模型:隐含狄利克雷分布(Latent Dirichlet Allocation,简称 ...

  8. ORACLE NOLOGGING研究

    熟悉oracle的人都知道.通过设置oracle的nologging选项,能够使某些操作高速完毕,风险是数据库备份可能失效.能够使用nologging的操作有非常多,搜集资料整理例如以下: 1.索引的 ...

  9. 基于spark1.4的Spark-Sql

    Author: kwu 基于spark1.4的Spark-Sql,spark1.4.1在7月15刚公布.提供较好sql支持 1.怎样启动Spark-Sql 启动脚本例如以下 #!/usr/bin/en ...

  10. C++求解汉字字符串的最长公共子序列 动态规划

        近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...