在高精度几何建模中,需要存储各种复杂的曲线,例如两条曲面的交线。这种复杂性源于这些曲线几乎无法同时以精确且实用的方式表示:其表示要么是近似的,要么极其复杂,以至于在不重写许多几何算法的情况下无法直接使用。因此,通常采用一种混合方法:为了保留最大精度,曲线以难以使用但精确的格式存储,而计算算法则使用以足够精度生成的曲线的简单近似值。
也许最方便的近似是埃尔米特三次样条(Hermite cubic spline),它易于生成且易于使用。不幸的是,随着近似精度的提高,三次样条需要更多的内存来存储,需要更多的时间来生成,并且所有算法在其上的运行速度都会变慢。三次样条近似具有四阶误差,这意味着精度提高 16 倍会使近似值的大小翻倍。
为了本题的目的,我们假设精度为 $\epsilon$ 的近似值占用 $M$ 字节的内存,其中 $M$ 的计算公式为:
$$M = \frac{s}{\sqrt[4]{\epsilon}}$$
生成这样的近似值需要消耗 $T$ 个 CPU 周期:
$$T = aM + b$$
这里 $s$、$a$ 和 $b$ 是一些给定的常数。
为了避免多次为同一条曲线生成相同的近似值,有时会将其“缓存”,即与曲线一起保存以备后用。在本题中,只有一条复杂曲线,你必须找到缓存其近似值的最佳方法,使得给定的 $N$ 个操作能够尽可能快地执行。
这些操作必须严格按照给定的顺序执行。任何操作都不能直接在复杂曲线上执行;相反,每个操作都必须给定一个可接受的曲线近似值。每个操作都有一个给定的“容差”(tolerance)$\delta$,它定义了对输入近似精度的要求。只有当 $\epsilon \le \delta$ 时,以精度 $\epsilon$ 生成的曲线近似值才足够好,可用于容差为 $\delta$ 的操作,否则它不能用于执行该操作。
操作执行时间使用以下公式计算:
$$T = cM + d$$
这里 $c$ 和 $d$ 是为每个操作独立定义的常数,$M$ 是所使用的曲线近似值的大小。回想一下,近似值的大小是根据上面提供的公式由其精度 $\epsilon$ 计算得出的。
找出在三种不同缓存策略下完成所有操作所需的最小时间:
- 关闭缓存(Caching off):无法在操作之间保存曲线近似值。一旦某个操作完成,所使用的近似值就会被丢弃,并且必须为下一个操作生成一个新的近似值。
- 缓存一个近似值(Cache one approximation):每次生成曲线近似值时,它都会被保存在缓存中,如果已存在旧的近似值,则将其覆盖(驱逐)。保存的近似值可以根据需要在未来的操作中多次使用,直到生成新的近似值。请注意,旧的近似值总是会被驱逐,即使新的近似值精度较低(即你不能在不缓存它的情况下生成近似值)。
- 无限制缓存(Unlimited caching):所有生成的近似值都以无限制的数量保存在缓存中。它们在未来都可以使用。为了执行某个操作,可以选择之前生成的任何近似值,当然前提是它对于该操作足够精确。
在所有三种变体中,缓存初始时都是空的,不包含任何近似值。在每个操作之前,你可以生成一个具有任何所需精度 $\epsilon > 0$ 的近似值,或者你也可以选择不生成任何内容。生成近似值所需的时间会累加到总操作执行时间中,你需要将其最小化。
输入格式
输入的第一行包含一个整数 $N$ —— 要执行的操作数量($1 \le N \le 10\,000$)。
第二行包含三个实数 $s$、$a$ 和 $b$ —— 影响近似值大小和生成时间的常数($10^{-3} \le s \le 10^3$,$10^{-4} \le a, b \le 10^4$)。
接下来的 $N$ 行描述操作。每行包含三个实数:$\delta$ —— 该操作所需的精度,以及 $c, d$ —— 影响操作执行时间的常数($10^{-12} \le \delta \le 1$,$10^{-4} \le c, d \le 10^4$)。
保证任意两个操作的容差 $\delta$ 要么完全相等,要么在相对意义上相差至少 $10^{-3}$。输入文件中的实数可以用指数格式表示,例如 1e-10。
输出格式
输出必须包含三个答案;每个答案包含 $N + 1$ 行。在答案之间,输出一行包含三个“等号”字符(===)。第一个答案针对关闭缓存的情况,第二个答案针对缓存一个近似值的情况,第三个答案针对无限制缓存的情况。
每个答案以一行包含一个实数 $\tau$ 开始,表示生成所有近似值和执行所有操作的总时间。接下来的 $N$ 行中,第 $i$ 行($1 \le i \le N$)必须说明在第 $i$ 个操作之前是否生成了新的曲线近似值。如果不需要生成近似值,则在该行输出 -1;如果必须生成近似值,则输出一个实数 $\epsilon$,定义新近似值的精度。
评测程序将以 $10^{-12}$ 的相对精度检查操作容差要求,并以 $10^{-8}$ 的相对精度检查总工作时间。建议以保留 15 位小数的指数格式输出所有实数。
样例
输入样例 1
1 1.12e-1 0.25 1.37 1.2345e-3 0.57e+2 37.019
输出样例 1
72.596453093690088396700768437928 1.2345e-3 === 7.259645309369008e+1 0.12345e-2 === 0.7259645309369008e+2 0.0012345
输入样例 2
4 1 2 1 1e-4 1e-3 1 1e-12 1 1 1e-8 1e+3 1 0.0625e-8 0.1 1
输出样例 2
103648.01 1e-4 1e-12 1e-8 0.0625e-8 === 103628 1e-12 -1 1e-8 0.0625e-8 === 103306.1 1e-08 1e-12 -1 -1
说明
在第一个样例中,只有一个操作,因此无论采用何种缓存策略,答案都是相同的;在任何情况下,你都必须生成一个精度等于操作容差的曲线近似值。请注意,这里的近似值大小不是整数,并且不会进行四舍五入。在样例输出中,展示了输出答案的几种不同格式。
考虑采用“缓存一个近似值”策略的第二个样例。从一开始就生成一个精度为 $10^{-12}$ 的近似值,并在前两个操作中使用它是合理的,因为第一个操作的执行时间几乎不受所用近似值大小的影响,这意味着使用更精确的近似值比生成另一个较小的近似值更便宜。第三个操作强烈依赖于近似值的大小,因此重新生成一个允许的最差精度的近似值是合理的。然而,这样的近似值不能用于第四个操作,因此必须为其生成一个新的、稍微更精确的近似值。
另一方面,无限制缓存策略使得在第四个操作中重复使用最初生成的精度为 $10^{-12}$ 的近似值变得合理。此外,可以提前生成精度为 $10^{-8}$ 的近似值,以便在第一个操作中也使用它。