[CTSC2009]魔幻花园 题解

P4490 [CTSC2009]魔幻花园 题解

洛谷链接

一、问题转化

原问题等价于求某个水平面上所有点围成凸包面积的最小值

首先考虑把三维问题转化到二维上:考虑到任意时刻所有点都在同一个水平面上,并且每个点的起点终点分别设为 \(S(sx,sy),T(tx,ty)\),那么他在 \(t\in[0,1]\) “时刻”的坐标为 \((T-S)\times t+S\)(这里把坐标当作向量运算),因此我们可以发现第三维坐标是无用的

注意到,转化后的题意是求 \(n\) 个动态点在某一时刻所形成的凸包面积的最小值

二、凸包形态

考虑什么时候凸包的形态会发生改变,我们发现他一定满足:某一个点从凸包内部经过某一条凸包上的边成为凸包上一点 或 某一个凸包上的点和他相邻的两个点形成的边退化为一条边,并在之后这个点不再存在于凸包上。

这两个条件里蕴含了一个非常重要的事件:三点共线

因此我们有一个思路:处理出所有三点共线的时刻(这样的时刻总共有 \(\Omicron(n^3)\) 个),然后暴力重新计算当前凸包形态。复杂度 \(\Omicron(n^4\log n)\)。(实测开 O2 能过)。

但是这显然不是正解,我们观察到每次只改变 \(\Omicron(1)\) 的信息,所以我们可以用链表(或者其它的)存储当前凸包结构并更新凸包(注意有的时候三点共线不改变凸包,需要特判)。复杂度 \(\Omicron(n^3\log n)\)

三、面积计算

我们考虑一般情况下是采用向量叉积计算多边形面积,又因为每个点的两维是关于时间的一次函数,所以面积是关于时间的二次函数,求这一次到下次可能的凸包更改事件之间凸包面积最小值并累计到答案里即可。

四、代码实现

代码太长了,所以放到剪贴板里了:

posted @ 2023-01-06 16:09  lazytag  阅读(86)  评论(0)    收藏  举报