bzoj2564: 集合的面积(闵可夫斯基和 凸包)
题面
题解
花了一个下午的时间调出了一个稍微能看的板子……没办法网上的板子和咱的不太兼容……
首先有一个叫做闵可夫斯基和的东西,就是给你两个点集\(A,B\),要你求一个点集\(C=\{x+y\mid x\in A,y\in B\}\),\(C\)就是\(A,B\)的闵可夫斯基和
我们考虑一下如果\(B\)只有一个点,那么\(C\)就可以看做\(A\)向某个方向平移一段距离,所以\(C\)就可以看做\(A\)向\(|B|\)个方向平移的点集的并集
然后我们现在想要求出\(C\)的凸包
首先原来不在\(A\)的凸包上的点平移之后也肯定不在凸包上,所以我们可以先求出\(A\)的凸包
我们先来考虑合并两个凸壳的情况。借(dao)用(yong)一下\(shadowice\)巨巨的图
对于图中每个点,如果它是\(i\)和\(j\)加起来得到的话,我们就把它标号为\((i,j)\),然后把这张图变成一个表格。然后我们发现,凸包中的点构成一个从\((1,1)\)到\((|A|,|B|)\)的路径,而且只能往上或往右走
那么我们就可以用双指针来维护了,设当前在\((i,j)\),每次看一下\((i+1,j)\)和\((i,j+1)\)两个点哪个在新的凸包上,然后走过去
为了避免我们求出的凸包是个有三点共线的假凸包,再对\(C\)跑一个凸包就好了(虽然这里求的是面积所以不跑也可以然而咱的板子不知为何不重新求就会\(WA\)而且重新求跑得比不重新求还要快……)
//minamoto
#include<bits/stdc++.h>
#define R register
#define inf 0x3f3f3f3f
#define ll long long
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=2e5+5;
struct node{
int x,y;
node(){}
node(R int xx,R int yy):x(xx),y(yy){}
inline node operator +(const node &b)const{return node(x+b.x,y+b.y);}
inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
inline ll operator *(const node &b)const{return 1ll*x*b.y-1ll*y*b.x;}
inline ll norm(){return 1ll*x*x+1ll*y*y;}
}A[N],B[N],C[N],st[N],P;
int ta,tb,tc,n,m,k,top;ll res;
inline bool cmp(const node &a,const node &b){
ll k=(a-P)*(b-P);
return k?(k>0?1:0):(a-P).norm()<(b-P).norm();
}
void Graham(node *A,int &ta){
P=node(inf,inf),k=0;
fp(i,1,ta)if(A[i].x<P.x||A[i].x==P.x&&A[i].y<P.y)P=A[i],k=i;
swap(A[1],A[k]),sort(A+2,A+1+ta,cmp);
st[0]=A[1],st[top=1]=A[2];
fp(i,3,ta){
while(top&&(A[i]-st[top-1])*(st[top]-st[top-1])>=0)--top;
st[++top]=A[i];
}
fp(i,0,top)A[i]=A[i+top+1]=st[i];
ta=top;
}
void merge(){
C[tc=1]=A[0]+B[0];
R int i=0,j=0;
while(i<=ta&&j<=tb){
node p1=(A[i]+B[j+1])-C[tc],p2=(A[i+1]+B[j])-C[tc];
p1*p2>=0?(C[++tc]=A[i]+B[j+1],++j):(C[++tc]=A[i+1]+B[j],++i);
}
for(;i<=ta;++i)C[++tc]=A[i]+B[j];
for(;j<=tb;++j)C[++tc]=A[i]+B[j];
Graham(C,tc);
fp(i,0,tc)res+=C[i]*C[i+1];
printf("%lld\n",res);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read(),ta=n,tb=m;
fp(i,1,n)A[i].x=read(),A[i].y=read();
fp(i,1,m)B[i].x=read(),B[i].y=read();
Graham(A,ta),Graham(B,tb);
merge();
return 0;
}
bzoj2564: 集合的面积(闵可夫斯基和 凸包)的更多相关文章
- BZOJ2564: 集合的面积(闵可夫斯基和 凸包)
题意 题目链接 Sol 这个东西的学名应该叫"闵可夫斯基和".就是合并两个凸包 首先我们先分别求出给出的两个多边形的凸包.合并的时候直接拿个双指针扫一下,每次选最凸的点就行了. 复 ...
- bzoj2564集合的面积
题目描述 对于一个平面上点的集合P={(xi,yi )},定义集合P的面积F(P)为点集P的凸包的面积. 对于两个点集A和B,定义集合的和为: A+B={(xiA+xjB,yiA+yjB ):(xiA ...
- bzoj2564 集合的面积
Description 对于一个平面上点的集合P={(xi,yi )},定义集合P的面积F(P)为点集P的凸包的面积. 对于两个点集A和B,定义集合的和为: A+B={(xiA+xjB,yiA+yjB ...
- bzoj 2564 集合的面积
Description 对于一个平面上点的集合P={(xi,yi )},定义集合P的面积F(P)为点集P的凸包的面积. 对于两个点集A和B,定义集合的和为: A+B={(xiA+xjB,yiA+yjB ...
- 洛谷P4557 [JSOI2018]战争(闵可夫斯基和+凸包)
题面 传送门 题解 看出这是个闵可夫斯基和了然而我当初因为见到这词汇是在\(shadowice\)巨巨的\(Ynoi\)题解里所以压根没敢学-- 首先您需要知道这个 首先如果有一个向量\(w\)使得\ ...
- HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015年百度之星程序设计大赛 - 初赛(1)
题目链接 题意:给出n个矩形,求能覆盖所有矩形的最小的矩形的面积. 题解:对所有点求凸包,然后旋转卡壳,对没一条边求该边的最左最右和最上的三个点. 利用叉积面积求高,利用点积的性质求最左右点和长度 ...
- poj 3348:Cows(计算几何,求凸包面积)
Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6199 Accepted: 2822 Description ...
- UVa 10652(旋转、凸包、多边形面积)
要点 凸包显然 长方形旋转较好的处理方式就是用中点的Vector加上旋转的Vector,然后每个点都扔到凸包里 多边形面积板子求凸包面积即可 #include <cstdio> #incl ...
- 闵可夫斯基和(Mincowsky sum)
一.概述 官方定义:两个图形A,B的闵可夫斯基和C={a+b|a∈A,b∈B}通俗一点:从原点向图形A内部的每一个点做向量,将图形B沿每个向量移动,所有的最终位置的并便是闵可夫斯基和(具有交换律) 例 ...
随机推荐
- 2014.8.25 CAD系统事件触发流程
各进近.离场.进场Arinc424数据录入界面在CADDataManager/UC/UCIAP(UCSID)下 UCAirport是一抽象用户控件类,在FormADHP初始化时实例化成airport控 ...
- flask系列二之基础知识
一.调试模式(debug模式) 1.设置debug模式 在app.run()中传入关键字参数debug,app.run(debug=Ture),就设置当前项目为debug模式.如下所示: # 从fla ...
- Java之Object类与instanceof关键字
Object类是所有类的父类: 我们上下代码: package com.learn.chap03.sec14; public class A { // 上面类A继承了Object类,因此又可这样定义: ...
- 自定义inputformat和outputformat
1. 自定义inputFormat 1.1 需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案 1.2 分析 小文件的优 ...
- Cause: java.sql.SQLException: 无效的列索引
今天调试代码发现“Cause: java.sql.SQLException: 无效的列索引”,查资料得出结论如下: 1.sql串的?号用''括了起来. 例如:select* from user t ...
- angularJS笔记之 服务
angular的服务有五种 第一种 constant 一般作为一种常量的服务 不可更改 第二种 value 用来注册服务对象或函数 可更改 第三种 factory 创建和配置服务的最快捷方式.可更改 ...
- Spring Cloud Zuul 2(基于配置中心的动态API网关)
在大体了解了API Zuul 和 配置中心Config后我们来尝试完成一个基于配置中心的动态API网关 创建项目 命名为api-gateway-dynamic-route并加入config 和 Zuu ...
- 关于windows的jdk
扯淡工作从web开发转向build automation,不知不觉已经一个半月了,各种学习熟悉build相关的流程和知识,比如ant, maven, jenkins 等CI技能.因为这一个半月学的东西 ...
- 微信小程序怎么获取用户输入
能够获取用户输入的组件,需要使用组件的属性bindchange将用户的输入内容同步到 AppService. <input id="myInput" bindchange=& ...
- RocketMq2