ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LG P4557 [JSOI2018]战争

2021-02-25 09:04:08  阅读:172  来源: 互联网

标签:Node LG const 部落 P4557 long 100005 JSOI2018 return


Description

九条可怜是一个热爱读书的女孩子。

在她最近正在读的一本小说中,描述了两个敌对部落之间的故事。第一个部落有 $n$ 个人,第二个部落有 $m$ 个人,每一个人的位置可以抽象成二维平面上坐标为 $(x_i,y_i)$的点。

在这本书中,人们有很强的领地意识,对于平面上的任何一个点,如果它被三个来自同一部落的人形成的三角形(可能退化成一条线段)包含(包括边界),那么这一个点就属于这一个部落的领地。如果存在一个点同时在两个阵营的领地中,那么这两个部落就会为了争夺这一个点而发生战争。

常年的征战让两个部落不堪重负,因此第二个部落的族长作出了一个英明的决定,他打算选择一个向量 $(dx,dy)$ ,让所有的族人都迁徙这个向量的距离,即所有第二阵营的人的坐标都变成 $(x_i+dx,y_i+dy)$

现在他计划了 $q$ 个迁徙的备选方案,他想要你来帮忙对每一个迁徙方案,计算一下在完成了迁徙之后,两个部落之间还会不会因为争夺领地而发生战争。

Solution

要求求出B凸包向指定方向移动一段距离是否与A凸包有交

考虑如果有交,那么存在$b+w=a$

整理得$w=a-b$,即为两个凸包的闵科夫斯基和

代码中的in函数有些bug

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,q,tot,top;
struct Node{
    long long x,y;
    Node operator +(const Node &z)const{return (Node){x+z.x,y+z.y};}
    Node operator -(const Node &z)const{return (Node){x-z.x,y-z.y};}
    long long operator *(const Node &z)const{return x*z.y-y*z.x;}
    long long dis(){return x*x+y*y;}
}A[100005],B[100005],base,sta[100005],s1[100005],s2[100005],s[200005];
inline int read(){
    int f=1,w=0;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return f*w;
}
bool cmp(Node a,Node b){return a*b>0||!(a*b)&&a.dis()<b.dis();}
void Graham(Node *a,int &N){
    int k=1;
    for(int i=2;i<=N;i++)if(a[i].y<a[k].y||a[i].y==a[k].y&&a[i].x<a[k].x)k=i;
    swap(a[k],a[1]),base=a[1];
    for(int i=1;i<=N;i++)a[i]=a[i]-base;
    sort(a+2,a+N+1,cmp),top=2,sta[1]=a[1],sta[2]=a[2];
    for(int i=3;i<=N;i++){
        while(top>=2&&(sta[top]-sta[top-1])*(a[i]-sta[top-1])<=0)--top;
        sta[++top]=a[i];
    }
    for(int i=1;i<=top;i++)a[i]=sta[i]+base;
    N=top;
}
void Minkowski(){
    for(int i=1;i<n;i++)s1[i]=A[i+1]-A[i];s1[n]=A[1]-A[n];
    for(int i=1;i<m;i++)s2[i]=B[i+1]-B[i];s2[m]=B[1]-B[m];
    s[tot=1]=A[1]+B[1];
    int pos1=1,pos2=1;
    while(pos1<=n&&pos2<=m)++tot,s[tot]=s[tot-1]+(s1[pos1]*s2[pos2]>=0?s1[pos1++]:s2[pos2++]);
    while(pos1<=n)++tot,s[tot]=s[tot-1]+s1[pos1++];
    while(pos2<=m)++tot,s[tot]=s[tot-1]+s2[pos2++];
}
bool in(Node x){
    if(x*s[1]>0||s[tot]*x>0)return false;
    int temp=lower_bound(s+1,s+tot+1,x,cmp)-s-1;
    return (x-s[temp])*(s[temp%tot+1]-s[temp])<=0;
}
int main(){
    n=read(),m=read(),q=read();
    for(int i=1;i<=n;i++)A[i]=(Node){read(),read()};
    for(int i=1;i<=m;i++)B[i]=(Node){-read(),-read()};
    Graham(A,n),Graham(B,m),Minkowski(),Graham(s,tot),base=s[1];
    for(int i=1;i<=tot;i++)s[i]=s[i]-base;
    for(;q;q--)s[0]=(Node){read(),read()},printf("%d\n",in(s[0]-base));
    return 0;
}
[JSOI2018]战争

 

标签:Node,LG,const,部落,P4557,long,100005,JSOI2018,return
来源: https://www.cnblogs.com/JDFZ-ZZ/p/14444953.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有