【学习笔记】Minkowski和
这还是个被我咕了N久的玩意
Minkowski和是一个奇怪的玩意
他长这样
$S={a+b \| a \in A , b \in B}$
AB可以是点集也可是向量集(显然)
他可以处理一些奇怪的东西
比如说我们来看这个题
你发现它要求的就是判断向量是否存在于A-B的Minkowski和里
那么你套上板子就做完了
好了你大概了解了Minkowski和是什么
我们现在来学怎么写
我们根据直观理解 Minkowski上的点一定是点集构成的凸包上的点
于是我们暴力求出所有点再进行一次求凸包就做完了 复杂度是 O(|A|*|B|)
它看起来就不是很优 肯定可以优化
我们发现很好的性质 凸包上的点它的斜率是单调的 所以显然可以TwoPointers优化
我们直接观察哪一个在外面拓展就可以了
代码实现扔这里了
//Love and Freedom.
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define inf 20021225
#define ll long long
#define db double
#define eps 1e-8
#define N 200010
using namespace std;
int read()
{
int f=,s=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-; ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return f*s;
}
struct poi
{
db x,y;
poi(){}
poi(db _x,db _y){x=_x,y=_y;}
};
typedef poi vec;
vec operator+(vec a,vec b){return vec(a.x+b.x,a.y+b.y);}
vec operator-(vec a,vec b){return vec(a.x-b.x,a.y-b.y);}
vec operator*(vec a,db b){return vec(a.x*b,a.y*b);}
vec operator/(vec a,db b){return vec(a.x/b,a.y/b);}
db cross(vec a,vec b){return a.x*b.y-a.y*b.x;}
db dot(vec a){return a.x*a.x+a.y*a.y;}
db len(vec a){return sqrt(dot(a));}
db dis(poi a,poi b){return len(b-a);}
poi p0;
int dcmp(db x){return x>eps?:x<-eps?-:;}
bool cmp(poi p1,poi p2){return dcmp(cross(p1-p0,p2-p0))==||(dcmp(cross(p1-p0,p2-p0))==&&dis(p0,p1)<dis(p0,p2));}
int gethull(poi *p,poi *h,int n)
{
p0=poi{1e18,1e18}; int id=;
for(int i=;i<=n;i++)
if(dcmp(p[i].x-p0.x)<||(dcmp(p[i].x-p0.x)==&&dcmp(p[i].y-p0.y)<))
id=i,p0=p[i];
swap(p[],p[id]); sort(p+,p+n+,cmp);
int top=; h[]=p[],h[]=p[];
for(int i=;i<=n;i++)
{
while(top>&&dcmp(cross(p[i]-h[top-],h[top]-h[top-]))>=) top--;
h[++top]=p[i];
}
return top;
}
poi A[N],B[N],p[N],C[N]; int na,nb,nc;
void minkowski()
{
A[na+]=A[],B[nb+]=B[];
C[nc=]=A[]+B[]; int i=,j=;
while(i<=na&&j<=nb)
{
vec v1=A[i+]+B[j]-C[nc],v2=A[i]+B[j+]-C[nc];
if(dcmp(cross(v1,v2))>=)
C[++nc]=A[i+]+B[j],i++;
else
C[++nc]=A[i]+B[j+],j++;
}
while(i<=na) C[++nc]=A[i]+B[j],i++;
while(j<=nb) C[++nc]=A[i]+B[j],j++;
}
bool check(poi w)
{
if((dcmp(cross(w-C[],C[nc]-C[]))==&&dis(C[nc],C[])>=dis(C[],w))||(dcmp(cross(w-C[],C[]-C[]))== && dis(C[],w)<=dis(C[],C[]))) return ;
int l=,r=nc,ans=;
while(l<=r)
{
int mid=l+r>>; poi p1=C[mid];
if(dcmp(cross(p1-C[],w-C[]))>=) l=mid+,ans=mid;
else r=mid-;
}
if(ans==nc||!ans) return ;
poi p1=C[ans],p2=C[ans+];
if(dcmp(cross(p1-w,p2-w))>=) return ;
return ;
}
int main()
{
int n1=read(),n2=read(),q=read();
for(int i=;i<=n1;i++) p[i].x=read(),p[i].y=read();
na=gethull(p,A,n1);
for(int i=;i<=n2;i++) p[i].x=-read(),p[i].y=-read();
nb=gethull(p,B,n2);
minkowski();
while(q--)
{
poi w; w.x=read(),w.y=read();
printf("%d\n",check(w));
}
return ;
}
注:1.求点是否在凸包内可以直接三角剖分以后二分在哪个极角区间内即可 2.至于为什么我想锤爆我自己的狗头呢 因为我的cmp写了dcmp>1调了一个世纪xtbl
另一道题
N校联考的题
(题面好像没法放/px)
就是我们首先猜结论 对于奇数和偶数的答案分别是凸的 那么考虑维护奇偶正负共四个凸的答案
我们分治去做 考虑如何合并
由于是凸的所以差分单调 那么我们就可以TwoPointers优化
然后求完答案继续维护差分数组
(这个玩意貌似还叫做分治max卷积/px)
发现这个过程其实也是在求Minkowski和
我的代码是展开讨论写的 于是它贼快但是贼长(
//Love and Freedom.
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define inf (ll)(1e18)
#define ll long long
#define N 500010
using namespace std;
int read()
{
int f=,s=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-; ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return f*s;
}
ll f[N][],d[N][],tmp[N][],a[N];
void solve(int l,int r)
{
if(l==r){f[l][]=a[l],f[l][]=a[l]; d[l][]=a[l],d[l][]=a[l]; return;}
int mid=l+r>>; solve(l,mid); solve(mid+,r);
int it1,it2; ll val;
for(int i=;i<=r-l+;i++) tmp[i][]=-inf,tmp[i][]=inf;
it1=l+,it2=mid+; val=d[l][];
for(int i=;i<=r-l+;i+=) // odd l odd+ r even-
{
tmp[i][]=max(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]>-d[it2][]-d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val-=d[it2][]+d[it2+][],it2+=;
}
it1=l,it2=mid+,val=d[mid+][];// printf("%lld\n",val);
for(int i=;i<=r-l+;i+=) // odd l even+ r odd+
{
tmp[i][]=max(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]>d[it2][]+d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val+=d[it2][]+d[it2+][],it2+=;
}
it1=l+,it2=mid+,val=d[l][]-d[mid+][];
for(int i=;i<=r-l+;i+=) // even l odd+ r odd-
{
tmp[i][]=max(tmp[i][],val);//printf("%d %d %d %lld\n",i,it1,it2,val);// printf("%lld\n",val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]>-d[it2][]-d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val-=d[it2][]+d[it2+][],it2+=;
}
it1=l,it2=mid+,val=;
for(int i=;i<=r-l+;i+=) // even l even+ r even+
{
tmp[i][]=max(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]>d[it2][]+d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val+=d[it2][]+d[it2+][],it2+=;
} it1=l+,it2=mid+; val=d[l][];
for(int i=;i<=r-l+;i+=) // odd l odd+ r even-
{
tmp[i][]=min(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]<-d[it2][]-d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val-=d[it2][]+d[it2+][],it2+=;
}
it1=l,it2=mid+,val=d[mid+][];
for(int i=;i<=r-l+;i+=) // odd l even+ r odd+
{
tmp[i][]=min(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]<d[it2][]+d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val+=d[it2][]+d[it2+][],it2+=;
}
it1=l+,it2=mid+,val=d[l][]-d[mid+][];
for(int i=;i<=r-l+;i+=) // even l odd+ r odd-
{
tmp[i][]=min(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]<-d[it2][]-d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val-=d[it2][]+d[it2+][],it2+=;
}
it1=l,it2=mid+,val=;
for(int i=;i<=r-l+;i+=) // even l even+ r even+
{
tmp[i][]=min(tmp[i][],val);
if(it2>r- && it1>mid-) break;
if(it2>r- || (it1<=mid-&&d[it1][]+d[it1+][]<d[it2][]+d[it2+][]))
val+=d[it1][]+d[it1+][],it1+=;
else
val+=d[it2][]+d[it2+][],it2+=;
}
//printf("%d %d\n",l,r);
for(int i=;i<=r-l+;i++)
f[l+i-][]=tmp[i][],
f[l+i-][]=tmp[i][];
//puts("");
d[l][]=f[l][],d[l][]=f[l][];
for(int i=l+;i<=r;i++)
d[i][]=f[i][]-f[i-][],
d[i][]=f[i][]-f[i-][];
}
int main()
{
int n=read();
for(int i=;i<=n;i++) a[i]=read();
solve(,n);
for(int i=;i<=n;i++)
printf("%lld ",f[i][]);
return ;
}
【学习笔记】Minkowski和的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- ucos实时操作系统学习笔记——任务间通信(消息)
ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...
随机推荐
- RCU原理分析
简介 RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制 ...
- 设计模式(2): 响应store中数据的变化
概述 最近最近做项目的时候总会思考一些大的应用设计模式相关的问题,我把自己的思考记录下来,供以后开发时参考,相信对其他人也有用. store里面响应数据变化 通常情况下,我们会把数据存在store里面 ...
- Linux_RHEL7_LDAP、Autofs服务
目录 目录 前言 LDAP 加入LDAP用户认证服务器 文件自动挂载服务autofs 前言 LDAP服务器,用作于网络用户的集中管理.在企业中员工的个人帐号一般采用集中管理的方式,在不同的系统平台上也 ...
- jQuery验证控件jquery.validate.js汉化
如需要修改,可在js代码中加入: jQuery.extend(jQuery.validator.messages, { required: "必选字段", remote: &q ...
- struts2默认action设置了却访问不到
1.错误原因 我的package中共有两个action,第一个是默认action,用于访问的action不存在时候的出错处理,第二个是通配符方式写的action,name采用*_*形式的全通配符.配置 ...
- 关于WordPress中字体加载慢的问题解决方案(转)
2016-04-15 最近发现Wordpress有时候加载的特别慢,于是就想办法找了下原因.之前听网上说是因为wordpress用的是Google的字体库,而且是每次都要加载,导致访问慢的,于是当时装 ...
- sklearn+nltk ——情感分析(积极、消极)
转载:https://www.iteye.com/blog/dengkane-2406703 步骤: 1 有标签的数据.数据:好评文本:pos_text.txt 差评文本:neg_text.txt ...
- jenkins初级使用篇
1.jenkins的初级使用 1.1 介绍 创建一个项目 可以看到当前登陆用户及用户权限 可以查看到所有构建过的项目的历史 系统管理 My Views:视图功能,我们可以自己创建一个自己的视图 系统管 ...
- xmake新增对Qt编译环境支持
在最新的xmake v2.2.1版本中,新增了对Qt SDK环境的支持,我们完全可以脱离Qt Creater进行Qt应用程序的开发,甚至配合vscode/idea等编辑器+xmake插件(xmake- ...
- 通过proxychains实现Ubuntu终端代理
1.在终端内使用代理,需要使用proxychains: sudo apt-get install proxychains 2.编辑 /etc/proxychains.conf sudo gedit / ...