[JSOI2018]战争(闵可夫斯基和)
害怕,可怜几何题
果然不会
题目就是说给你两个凸包,每次询问给你一个向量 \(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]战争(闵可夫斯基和)的更多相关文章
- BZOJ5317:[JSOI2018]战争(闵可夫斯基和)
令 \(a\in A,b\in B\) 则移动向量 \(\omega\) 使得存在 \(b+\omega=a\) 那么 \(\omega\) 需要满足 \(\omega=a−b\) 黑科技:闵可夫斯基 ...
- [BZOJ5317][JSOI2018]部落战争(闵可夫斯基和)
对于点集$A$,$B$,闵可夫斯基和$C=\{(x1+x2,y1+y2)|(x1,x2)\in A,(y1,y2)\in B\}$.由此可知,对于两个凸包$A$,$B$的闵可夫斯基和$C$满足,$C$ ...
- 洛谷P4557 [JSOI2018]战争(闵可夫斯基和+凸包)
题面 传送门 题解 看出这是个闵可夫斯基和了然而我当初因为见到这词汇是在\(shadowice\)巨巨的\(Ynoi\)题解里所以压根没敢学-- 首先您需要知道这个 首先如果有一个向量\(w\)使得\ ...
- 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 ...
- HHHOJ #151. 「NOI模拟 #2」Nagisa
计算几何板子题(我才没有拷板子的说--) 众所周知,三角形的重心坐标是\((\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})\) 然后我们发现如果我们有一个点集 ...
- 【学习笔记】Minkowski和
这还是个被我咕了N久的玩意 Minkowski和是一个奇怪的玩意 他长这样 $S={a+b \| a \in A , b \in B}$ AB可以是点集也可是向量集(显然) 他可以处理一些奇怪的东西 ...
随机推荐
- python操作JIRA的库简单操作
因公司需要,我们开发的PRISM又需要和JIRA对接啦, 今天找了一个JIRA库撸了一发~~~ jira库地址: https://pypi.python.org/pypi/jira/1.0.3 简单操 ...
- 修改oracle客户端的字符集
客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter, 表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表 方法有 : ...
- 利用junit对springMVC的Controller进行测试
本文转自http://www.tuicool.com/articles/7rMziy 平时对junit测试service/DAO层已经很熟悉不过了,如果不了解,可以猛戳这里,但是我们要测试contro ...
- 配置db账号和密码时一定注意空格问题、空行问题否则连接报错
#postgresql dbpg.datasource.type=com.alibaba.druid.pool.DruidDataSourcepg.datasource.driverClassName ...
- iOS_25_彩票设置的cell的数据源模型的封装
组模型的封装 SettingGroup // // SettingGroup.h // 25_彩票 // // Created by beyond on 14-8-28. // Copyright ( ...
- ArcEngine 地图导航 查找路径 经纬度坐标导航 最优路径分析
本文来自CSDN博客.转载请标明出处 http//blog.csdn.net/zdb330906531 需求:依据经纬度坐标.取得两个起点与终点,显示最优路径实现导航. 參考官方样例后.我在arcMa ...
- 检測wifi是否须要portal验证 公共场所wifi验证
何为wifi portal验证? 平时在商场,咖啡厅,银行等公共场所.我们手机提示:有可用WLAN.这些WIFI能够直接连接,不须要password,但须要我们手动在手机网页上进行验证,通常是输入一个 ...
- luogu1168 中位数
题目大意 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], -, A[2k - 1]的中位数.即前1,3,5,--个数的中位数. 题解 ...
- Makefile中用宏定义进行条件编译(gcc -D)/在Makefile中进行宏定义-D【转】
本文转载自:http://blog.csdn.net/maopig/article/details/7230311 在源代码里面如果这样是定义的:#ifdef MACRONAME//可选代码#en ...
- hdoj--5093--Battle ships(二分图经典建图)
Battle ships Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tot ...