• 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;
    }
    
  • 相关阅读:
    codeforces 图论题目集(持续更新)
    整数快速幂
    Codeforces Codeforces Global Round 5 C2
    POJ 1061
    扩展欧几里德算法(数论)
    Codeforces Round #592 (Div. 2) 1224D
    Codeforces Round #582 (Div. 3) G. Path Queries
    2019 kickstart A轮 B 题
    P3379 【模板】最近公共祖先(LCA)
    bzoj 2002 分块
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/13822764.html
Copyright © 2020-2023  润新知