题解:P11370 [Ynoi2024] 堕天作战/虚空处刑
Statement
给定一个包含
数据范围:
Solution
题目相当于给定
线段的相交问题不容易处理,考虑将线段变为直线。如果对横坐标分治,那么一条包含整个分治区间的线段就可以视作直线。这样每条线段就可以被放进
先考虑多边形的边被视作直线的情况。由于是简单多边形,所以所有多边形的边必然不相交于非端点的位置,即分治区间内不存在交点。那么可以对多边形的边排序,对于每条询问的线段,一边二分一边判定是否于多边形的边相交即可。
接下来只需要考虑询问的线段被视作直线的情况。此时多边形的边可以分为若干组,每组内部的线段首尾相连形成一条折线,组之间的线段不相交。
设分治区间的两条竖直的直线为
但是只考虑这种情况是不够的,因为可能存在这样的直线:
此时直线与绿色多边形相交,但不与绿色多边形与直线
如何求出凸包?考虑按照每个折线与
如何判断直线是否与凸包相交?二分找到与直线斜率最接近的一个点,并判断点和询问的直线的方向即可。
于是我们对左上、右上、左下、右下分别做一遍维护凸包的过程即可完成判断。
还需要注意的一点是,当询问的线段和多边形的边均垂直于横坐标轴时,两条线段均无法被分治处理,所以还需要额外对这些线段做一次排序、扫描线处理。
由于每条线段被分治到
Note
代码太史山了就不放了,这里是一些做这道题的经历。我的代码总长 17.46 KiB,用时约十个小时,祝大家好运。
Solution (English)
The problem is equivalent to given
The problem of line segment intersection is not easy to handle, so let's consider transforming the line segments into straight lines. If we perform a divide-and-conquer based on the x-coordinates, a line segment that covers the entire divide-and-conquer interval can be treated as a straight line. This way, each line segment can be placed into
First, let's consider the case where the polygon edges are treated as straight lines. Since it's a simple polygon, all the edges must not intersect at any point other than at their endpoints, meaning that no intersections exist within the divide-and-conquer intervals. We can then sort the polygon edges, and for each query line segment, we can perform binary search while simultaneously checking if it intersects with the polygon edges.
Next, we need to consider the case where the query line segments are treated as straight lines. In this case, the polygon edges can be divided into several groups, with the line segments within each group being connected end-to-end to form a polyline. The line segments between groups do not intersect.
Let the two vertical lines of the divide-and-conquer interval be
However, considering only this case is not enough, because there may exist such lines:
In this case, the line intersects the green polygon but does not intersect the interval where the green polygon intersects the line
To find the convex hull, consider sorting the polylines based on the intervals where they intersect with
To determine if a line intersects the convex hull, we perform binary search to find the point with the closest slope to the query line and check the direction of the point relative to the query line.
Thus, we can complete the checking process by maintaining the convex hulls for the upper-left, upper-right, lower-left, and lower-right directions separately.
One more thing to note is that when both the query line segment and the polygon edge are perpendicular to the x-axis, neither of these line segments can be processed using divide-and-conquer. Therefore, we need to perform additional sorting and sweep line processing for these line segments.
Since each line segment is divided into