• P4557 [JSOI2018]战争


    P4557 [JSOI2018]战争

    链接

    P4557 [JSOI2018]战争

    题解

    闵可夫斯基和的板子题。
    题目给了两个点集(A),(B),显然可以先把凸包搞出来。。
    然后多次询问,每次询问一个向量是否满足存在 (b+w) (=) (a)
    移项之后就是问是否满足存在(w=a-b) ,把(B)中的每个点坐标取反,然后求闵可夫斯基和就可以了。

    (Code)

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N=2e5+10;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void print(LL x){
        if(x>9) print(x/10);
        putchar(x%10+'0');
    }
    
    struct P{
    	LL x,y;
    	LL len(){return x*x+y*y;}
    	P(LL xx=0,LL yy=0){x=xx;y=yy;}
    };
    P operator - (P x,P y){return P(x.x-y.x,x.y-y.y);}
    P operator + (P x,P y){return P(x.x+y.x,x.y+y.y);}
    LL operator * (P x,P y){return x.x*y.y-x.y*y.x;}
    
    bool cmp1(P x,P y){return x.y<y.y||(x.y==y.y&&x.x<y.x);}
    bool cmp2(P x,P y){return x*y>0||(x*y==0&&x.len()<y.len());}
    void Convex(P *A,int &n){
    	sort(A+1,A+1+n,cmp1);
    	P O=A[1];
    	for(int i=2;i<=n;++i){
    		A[i]=A[i]-A[1];
    	}
    	sort(A+2,A+1+n,cmp2);
    	int tp=1;
    	for(int i=2;i<=n;++i){
    		while(tp>=3&&((A[i]-A[tp-1])*(A[tp]-A[tp-1])>=0)) --tp;
    		A[++tp]=A[i];
    	}
    	n=tp;
    	for(int i=2;i<=n;++i) A[i]=A[i]+O;
    	return;
    }
    P D[N];
    
    int tot;
    int n,m,Q; 
    P C1[N],C2[N],a1[N],a2[N];
    void Minkowski(){
    	for(int i=1;i<n;++i) a1[i]=C1[i+1]-C1[i];a1[n]=C1[1]-C1[n];
    	for(int i=1;i<m;++i) a2[i]=C2[i+1]-C2[i];a2[m]=C2[1]-C2[m];
    	D[tot=1]=C1[1]+C2[1];
    	LL p1=1,p2=1;
    	while(p1<=n&&p2<=m) ++tot,D[tot]=D[tot-1]+(a1[p1]*a2[p2]>=0?a1[p1++]:a2[p2++]);
    	while(p1<=n) ++tot,D[tot]=D[tot-1]+a1[p1++];
    	while(p2<=m) ++tot,D[tot]=D[tot-1]+a2[p2++];
    }
    
    int init(P E){
    	if(E*D[2]>0||D[tot]*E>0) return 0;
    	LL ps=lower_bound(D+1,D+tot+1,E,cmp2)-D-1;
    	return (E-D[ps])*(D[ps%tot+1]-D[ps])<=0;
    } 
    
    int main(){
    	scanf("%d%d%d",&n,&m,&Q);
    	for(int i=1;i<=n;++i){
    		scanf("%lld%lld",&C1[i].x,&C1[i].y);
    	}
    	for(int i=1;i<=m;++i){
    		scanf("%lld%lld",&C2[i].x,&C2[i].y);
    		C2[i].x=-C2[i].x;C2[i].y=-C2[i].y;
    	}
    	Convex(C1,n);
    	Convex(C2,m);
    	Minkowski();
    	Convex(D,tot);
    	P O=D[1],E;
    	for(int i=1;i<=tot;++i) D[i]=D[i]-O;
    	while(Q--){
    		scanf("%lld%lld",&E.x,&E.y);
    		printf("%d
    ",init(E-O));
    	}
    	return 0;
    }
    
  • 相关阅读:
    JavaScript数组方法
    模拟js数组indexOf方法
    js数组排序
    发布Exchange的SMTP,POP3服务器:ISA2006系列之十八
    用智能卡构建身份验证的马其诺防线:ISA2006系列之二十三
    Java与CSharp的相同与不同
    创建可传递的林信任,Active Directory系列之二十
    组策略指派Office2003分发,Active Directory系列之二十三
    发布Exchange的RPC以及RPC Over HTTPS:ISA2006系列之十九
    初步理解组策略,Active Directory系列之二十一
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/13822764.html
Copyright © 2020-2023  润新知