A - CF549E Sasha Circle
题意
平面内有两个点集N,MN,MN,M,问能否在平面内画一个圆,使得NNN和MMM这两个点集恰好有一个点集所有点严格在圆内,另一个点集所有点严格在圆外(即两个点集都不能有点在圆上)。
坐标为[−104,104][-10^4,10^4][−104,104]的整数,∣N∣,∣M∣≤104|N|,|M|\le 10^4∣N∣,∣M∣≤104。
Sol
朴素算法
枚举哪个集合在圆内,假设在圆内的集合是AAA,在圆外的集合是BBB。
枚举AAA中的两个点p,qp,qp,q,令圆过这两个点,则只需要再知道圆心就可以确定圆。考虑剩下的点,“限制某个点在圆内/圆外”可以转化成对圆心的限制,最后圆心可能取的位置一定是pqpqpq中垂线上的一条线段。由于这道题要求点和圆不能交,所以取值范围的线段的端点不能够重合。容易发现,当取值范围的线段端点没有重合的时候,我们通过一定的调整就可以使得圆不经过p,qp,qp,q。
这样做的复杂度是O(∣A∣2⋅(∣A∣+∣B∣))O( |A|^2 \cdot (|A| + |B|))O(∣A∣2⋅(∣A∣+∣B∣))的。
优化
把这个问题放到三维坐标系中,原来的点在xOyxOyxOy这个平面上。
考虑x2+y2=zx^2 +y^2 = zx2+y2=z这个曲面,把A,BA,BA,B这两个点集中的点垂直于xOyxOyxOy地投影到这个曲面上得到点集A′,B′A',B'A′,B′。考虑任意一个不与xOyxOyxOy垂直的平面ax+by+z=cax + by + z =cax+by+z=c,与曲面的解析式联立可以得到x2+ax+y2+by=cx^2+ax+y^2+by=cx2+ax+y2+by=c,这是圆方程的形式。所以,曲面z=x2+y2z = x^2 + y^2z=x2+y2与任意一个不垂直于xOyxOyxOy的平面的交集,垂直投影到平面xOyxOyxOy上,得到的一定是一个圆;一个曲面上的点投影到xOyxOyxOy之后在圆内,当且仅当在曲面上它在那个平面的下方。
所以,问题转化成判断能否找出一个不垂直于xOyxOyxOy的平面,A′A'A′所有点都在平面的下方,B′B'B′所有点都在平面的上方。
显然只有A′A'A′的上凸壳的这些平面是有用的。
由于曲面z=x2+y2z = x^2 + y^2z=x2+y2是向下凸的,所以A′A'A′上凸壳顶点的点的投影一定是AAA的凸包端点。
而上凸壳上的某一个平面,它与这个曲面的交在xOyxOyxOy上的投影,实际上是平面在xOyxOyxOy上的投影的外接圆。也就是说,上凸壳上的每一个多边形在xOyxOyxOy的投影都满足:1)所有端点共圆;2)外接圆都包含了AAA中的所有点。
如图所示(官方题解里的图):
故而我们可以:将AAA的凸包划分成若干个三角形,使得每一个三角形的外接圆都包含AAA中的所有点,然后对三角形上的每一条边进行前面的朴素算法。
由于三维中的上凸壳是存在且唯一的,所以这样的划分方式一定存在,并且当AAA没有四点共圆的时候是唯一的。
这种三角剖分称为Anti-Delaunay Triagulation。
求出三角剖分之后计算答案的复杂度是O(C23(∣N∣+∣M∣))O (C^{2\over 3}(|N|+|M|))O(C32(∣N∣+∣M∣))(其中CCC是坐标绝对值大小,C23C^{2\over 3}C32是凸包点数的最大值),可以接受。
现在还剩下的问题是如何在O((C23)2)O((C^{2\over 3})^2)O((C32)2)以下的时间复杂度内求出三角剖分。
求一个凸多边形的Anti-Delaunay Triagulation
首先随便选择多边形的一条边p1p2p_1p_2p1p2,然后找出多边形上的另一个端点pkp_kpk使得p1,p2,pkp_1,p_2,p_kp1,p2,pk确定圆的半径最大。由于凸多边形的三角剖分一定存在,所以这个外接圆一定包含凸多边形的所有端点;又因为当没有四点共圆的情况的时候三角剖分唯一,所以这个多边形的三角剖分中一定有△p1p2pk\triangle p_1p_2p_k△p1p2pk。这样我们就将原问题转化成了由p1pkp_1p_kp1pk和p2pkp_2p_kp2pk划开的两个规模更小的子问题,递归求解即可。
设多边形的端点数为nnn,则复杂度O(n2)O(n^2)O(n2)。
实现细节
-
在进行那个朴素算法的时候,首先没有必要去算圆心ooo,因为我们只需要确定从op⃗\vec{op}op到oq⃗\vec{oq}oq的角的大小就可以了。而这个角的大小等于圆上的第三个点与p,qp,qp,q的夹角的二分之一。所以我们只需要考虑A,BA,BA,B中的其它点与p,qp,qp,q的夹角带来的限制就可以了。而比较角的大小这里用比较余切值的大小比较方便,只需要特殊考虑点与pqpqpq贡献的情况。
假设我们现在在检查的点是uuu,∠puq=α,∠poq=β\angle puq = \alpha,\angle poq=\beta∠puq=α,∠poq=β,注意这里角的大小是带符号的。-
要求uuu在圆内:
- pu⃗\vec{pu}pu在pq⃗\vec{pq}pq的逆时针方向:那么则要求cotβ>cotα\cot \beta > \cot \alphacotβ>cotα。
- pu⃗\vec{pu}pu在pq⃗\vec{pq}pq的顺时针方向:那么则要求cotβ<cotα\cot \beta < \cot \alphacotβ<cotα。
-
要求uuu在圆外:
- pu⃗\vec{pu}pu
-