[JSOI2018]战争

≡放荡痞女 提交于 2019-12-02 02:54:44

题目描述

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

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

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

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

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

输入格式

第一行输入三个整数 n,m,qn,m,qn,m,q,表示两个部落里的人数以及迁徙的备选方案数。

接下来 nnn 行每行两个整数 xi,yix_i,y_ixi,yi​​ 表示第一个部落里的人的坐标。

接下来 mmm 行每行两个整数 xi,yix_i,y_ixi,yi​​ 表示第二个部落里的人的坐标。

接下来 qqq 行每行两个整数 dxi,dyidx_i,dy_idxi,dyi​​ 表示一个迁徙方案。

输入数据保证所有人的坐标两两不同。

输出格式

对于每个迁徙方案,输出一行一个整数,000 表示不会发生冲突,111 表示会发生冲突。

输入输出样例

输入 #1 
4 4 3
0 0
1 0
0 1
1 1
-1 0
0 3
0 2
0 -1
0 0
2 3
0 -1
输出 #1
1
0
设a,b为两个部落构成的凸包
b+d=a等价于d=a-b
即取反b,求出凸包,再用Minkowski和合并两凸包
查询用二分查询向量d所在区间,用叉积判断是否在凸包内
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 typedef long long lol;
  7 struct Node
  8 {
  9     lol x,y;
 10     Node operator + (const Node &b) const
 11     {
 12         return (Node){x+b.x,y+b.y};
 13     }
 14     Node operator - (const Node &b) const
 15     {
 16         return (Node){x-b.x,y-b.y};
 17     }
 18 }a[100005],b[100005],sa[200005],sb[200005],sta[200005],bs,s1[200005],s2[200005],s[200005];
 19 int n,m,q,top;
 20 bool cmp(Node a,Node b)
 21 {
 22     if (a.y==b.y) return a.x<b.x;
 23     return a.y<b.y;
 24 }
 25 lol cross(Node a,Node b)
 26 {
 27     return (a.x*b.y-a.y*b.x);
 28 }
 29 lol dist(Node a)
 30 {
 31     return a.x*a.x+a.y*a.y;
 32 }
 33 bool cmp1(Node A,Node B)
 34 {
 35     lol t=cross((a[1]-A),(a[1]-B));
 36     if (t==0) return dist(a[1]-A)<dist(a[1]-B);
 37     return t>0;
 38 }
 39 bool cmp2(Node A,Node B)
 40 {
 41     lol t=cross((b[1]-A),(b[1]-B));
 42     if (t==0) return dist(b[1]-A)<dist(b[1]-B);
 43     return t>0;
 44 }
 45 int grahama(int N)
 46 {int i;
 47     sort(a+1,a+N+1,cmp);
 48     sort(a+2,a+N+1,cmp1);
 49     top=0;
 50     sa[++top]=a[1];
 51     if (N==1) return 1;
 52     sa[++top]=a[2];
 53     for (i=3;i<=N;i++)
 54     {
 55         while (top>1&&cross(a[i]-sa[top-1],sa[top]-sa[top-1])>=0) top--;
 56         top++;
 57         sa[top]=a[i];
 58     }
 59     sa[top+1]=a[1];
 60     return top;
 61 }
 62 int grahamb(int N)
 63 {int i;
 64     sort(b+1,b+N+1,cmp);
 65     sort(b+2,b+N+1,cmp2);
 66     top=0;
 67     sb[++top]=b[1];
 68     if (N==1) return 1;
 69     sb[++top]=b[2];
 70     for (i=3;i<=N;i++)
 71     {
 72         while (top>1&&cross(b[i]-sb[top-1],sb[top]-sb[top-1])>=0) top--;
 73         top++;
 74         sb[top]=b[i];
 75     }
 76     sb[top+1]=b[1];
 77     return top;
 78 }
 79 bool cmpp(Node A,Node B)
 80 {
 81     lol t=cross((s[1]-A),(s[1]-B));
 82     if (t==0) return dist(s[1]-A)<dist(s[1]-B);
 83     return t>0;
 84 }
 85 int grahams(int N)
 86 {int i;
 87     sort(s+1,s+N+1,cmp);
 88     sort(s+2,s+N+1,cmpp);
 89     top=0;
 90     sta[++top]=s[1];
 91     if (N==1) return 1;
 92     sta[++top]=s[2];
 93     for (i=3;i<=N;i++)
 94     {
 95         while (top>1&&cross(s[i]-sta[top-1],sta[top]-sta[top-1])>=0) top--;
 96         top++;
 97         sta[top]=s[i];
 98     }
 99     sta[top+1]=s[1];
100     return top;
101 }
102 bool cmp3(Node A,Node B)
103 {
104     return cross(A,B)>0||(cross(A,B)==0&&dist(A)<dist(B));
105 }
106 lol find(Node A)
107 {
108     if(cross(A,sta[1])>0||cross(sta[top],A)>0) return 0;
109     lol ps=lower_bound(sta+1,sta+top+1,A,cmp3)-sta-1;
110     return cross((A-sta[ps]),(sta[ps%top+1]-sta[ps]))<=0;
111 }
112 void Minkowski()
113 {
114     for(lol i=1;i<n;i++) s1[i]=sa[i+1]-sa[i];s1[n]=sa[1]-sa[n];
115     for(lol i=1;i<m;i++) s2[i]=sb[i+1]-sb[i];s2[m]=sb[1]-sb[m];
116     top=1;
117     s[top]=sa[1]+sb[1];
118     lol i=1,j=1;
119     while(i<=n&&j<=m) ++top,s[top]=s[top-1]+(cross(s1[i],s2[j])>=0?s1[i++]:s2[j++]);
120     while(i<=n) ++top,s[top]=s[top-1]+s1[i++];
121     while(j<=m) ++top,s[top]=s[top-1]+s2[j++];
122 }
123 int main()
124 {int i,j;
125 lol dx,dy;
126     cin>>n>>m>>q;
127     for (i=1;i<=n;i++)
128     scanf("%lld%lld",&a[i].x,&a[i].y);
129     for (i=1;i<=m;i++)
130     scanf("%lld%lld",&b[i].x,&b[i].y),b[i].x=-b[i].x,b[i].y=-b[i].y;
131     n=grahama(n);
132     m=grahamb(m);
133     Minkowski();
134     top=grahams(top);
135     bs=sta[1];
136     for (i=1;i<=top;i++)
137     sta[i]=sta[i]-bs;
138     
139     for (i=1;i<=q;i++)
140     {
141         scanf("%lld%lld",&dx,&dy);
142         if (find((Node){dx,dy}-bs)) 
143         printf("1\n");
144         else printf("0\n");
145     }
146 } 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!