【bzoj2852】【vijos1504】强大的区间 题解

来源:互联网 发布:wind数据库使用方法 编辑:程序博客网 时间:2024/06/05 17:26

题目大意

      给出两个实数 a、b,我们要求一个最小的正整数 k,使得区间 [ak, bk] 是一个包含至少一个整数的区间。
      比如 a=1.2,b=1.3,当 k=4 时,区间为 [4.8, 5.2],包含了整数 5。
      a、b 的整数部分不超过maxlongint,小数部分不超过300位。

二分!?

      显然 k 是既有上界又有下界的,所以第一眼考虑二分。
      然而画一下数轴你就发现,这题没有二分性质。
      具体就不证了,举个栗子就好了:0.45 和 0.55,当 k=2 或 4 时,都合法,但是 k=3 时却不合法。

巧妙的类欧思路

      首先,[a, b] 的答案与 [a-1, b-1] 是相同的。因此我们可以先把这个区间变到 a<1 先。
      如果此时 b>=1 或者 a=0,那么答案就是1,不然的话就变成了这样解一个不等式:a×k <= t <= b×k,其中 k、t 为正整数。
      把 k 除掉,再取倒数,结果变成这个样子:t/b <= k <= t/a。
      然后我们发现问题变成了求区间 [1/a, 1/b] 的答案,这就迭代下去了。
      综上所述就是:对于每一层,我们有参数 ab,先把区间化成 [a,b],其中 a<1。若 b>=1 或者 a=0,则返回 a,否则处理下一层(参数为 1/b1/a)并得到返回值 t,然后返回 a×t。注意,第一层作为最终答案层,返回情况跟别的层有所不同,处理一下。

精度

      据说这题精度不好搞!?
      我觉得首先要把小数化成分数吧,然后往后都用分数计算,这会好算很多。

时间复杂度

      这个过程是典型的类欧几里得算法思想:先把一个数变得比另一个数小,然后交换两个数,重复这一过程。
      所以时间就跟类欧一样,都是 log。

0 0