QOJ.ac

QOJ

حد الوقت: 2.0 s حد الذاكرة: 256 MB مجموع النقاط: 100

#17842. Caching approximations

الإحصائيات

在高精度几何建模中,需要存储各种复杂的曲线,例如两条曲面的交线。这种复杂性源于这些曲线几乎无法同时以精确且实用的方式表示:其表示要么是近似的,要么极其复杂,以至于在不重写许多几何算法的情况下无法直接使用。因此,通常采用一种混合方法:为了保留最大精度,曲线以难以使用但精确的格式存储,而计算算法则使用以足够精度生成的曲线的简单近似值。

也许最方便的近似是埃尔米特三次样条(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}$ 的近似值,以便在第一个操作中也使用它。

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.