zoukankan      html  css  js  c++  java
  • P4557 [JSOI2018]战争 题解

    Luogu

    Description.

    有两个部落,每个部落有一些营地,对应为二维平面上的一些点。
    定义两个部落会发生重读,当且仅当满足以下条件之一。
    定义一个部落的控制范围是它所有营地构成的凸包。
    定义两个部落会发生冲突,当且仅当一个部落的一个营地在另一个部落控制范围内。
    现在,向往核平的第二个部落首领决定搬迁避免战争,具体的,他会确定一个向量,所有营地平移这个向量。
    他给出了 \(Q\) 个方案,他想问你每个方案能否成功避免战争。

    Solution.

    首先,我们考虑这个平移,会让我们想到闵可夫斯基和。
    但是闵可夫斯基和是两个凸包之间的关系。
    我们考虑 \(B+\vec p=B'\Leftrightarrow A\),是不是可以直接认为 \(\vec p\Leftrightarrow A-B\)
    然后我们设 \(-B\) 等于 \(B\) 坐标取反后得到的凸包。
    然后判断 \(\vec p\) 是否在 \(A+(-B)\) 内即可。

    Coding.

    点击查看弱小代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),bz=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) bz=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	bz?x=-x:x;
    }/*}}}*/
    int n,m,Q,tt,CX[200005];
    struct Vec
    {
    	ll x,y;
    	inline Vec operator+(Vec b) const {return(Vec){x+b.x,y+b.y};}
    	inline Vec operator-(Vec b) const {return(Vec){x-b.x,y-b.y};}
    	inline ll operator^(Vec b) const {return x*b.x+y*b.y;}
    	inline ll operator*(Vec b) const {return x*b.y-y*b.x;}
    	inline ll dis() {return x*x+y*y;}
    }a[200005],b[200005],r[200005],v1[200005],v2[200005];
    inline char cmp(Vec a,Vec b) {return a*b>0||(a*b==0&&a.dis()<b.dis());}
    inline void convex(int &n,Vec *a)
    {
    	int tp=0;sort(a+1,a+n+1,[](Vec a,Vec b){return fabs(a.y-b.y)<1e-8?a.x<b.x:a.y<b.y;});
    	Vec bas=a[1];CX[tp=1]=1;for(int i=1;i<=n;i++) a[i]=a[i]-bas;
    	sort(a+2,a+n+1,cmp);for(int i=2;i<=n;CX[++tp]=i++)
    		while(tp>1&&(a[i]-a[CX[tp-1]])*(a[CX[tp]]-a[CX[tp-1]])>=0) tp--;
    	for(int i=1;i<=tp;i++) a[i]=a[CX[i]]+bas;
    	n=tp,a[n+1]=a[1];
    }
    inline void solve()
    {
    	v1[n]=a[1]-a[n];for(int i=1;i<n;i++) v1[i]=a[i+1]-a[i];
    	v2[m]=b[1]-b[m];for(int i=1;i<m;i++) v2[i]=b[i+1]-b[i];
    	int w1=1,w2=1;r[tt=1]=a[1]+b[1];
    	while(w1<=n&&w2<=m) ++tt,r[tt]=r[tt-1]+(v1[w1]*v2[w2]>=0?v1[w1++]:v2[w2++]);
    	while(w1<=n) ++tt,r[tt]=r[tt-1]+v1[w1++];
    	while(w2<=m) ++tt,r[tt]=r[tt-1]+v2[w2++];
    }
    inline char chk(Vec a)
    {
    	if(a*r[1]>0||r[tt]*a>0) return 0;
    	int wh=lower_bound(r+1,r+tt+1,a,cmp)-r-1;
    	return (a-r[wh])*(r[wh%tt+1]-r[wh])<=0;
    }
    int main()
    {
    	read(n),read(m),read(Q);Vec base,in;
    	for(int i=1;i<=n;i++) read(a[i].x),read(a[i].y);
    	for(int i=1;i<=m;i++) read(b[i].x),read(b[i].y),b[i].x=-b[i].x,b[i].y=-b[i].y;
    	convex(n,a),convex(m,b),solve(),convex(tt,r);
    	base=r[1];for(int i=tt;i>=1;i--) r[i]=r[i]-r[1];
    	while(Q--) read(in.x),read(in.y),printf("%d\n",chk(in-base));
    	return 0;
    }
    
  • 相关阅读:
    在IE和Firfox获取keycode
    using global variable in android extends application
    using Broadcast Receivers to listen outgoing call in android note
    help me!virtual keyboard issue
    using iscroll.js and iscroll jquery plugin in android webview to scroll div and ajax load data.
    javascript:jquery.history.js使用方法
    【CSS核心概念】弹性盒子布局
    【Canvas学习笔记】基础篇(二)
    【JS核心概念】数据类型以及判断方法
    【问题记录】ElementUI上传组件使用beforeupload钩子校验失败时的问题处理
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15150194.html
Copyright © 2011-2022 走看看