反质数

反质数( 数学\(\star \))

  • 时限:\(1s\) 内存:\(256M\)

Descrption

  • 对于任何正整数 \(x\),其约数的个数记作 \(g(x)\)。例如 \(g(1)=1,g(6)=4\)
  • 如果某个正整数 \(x\) 满足:
    • 对任意的 \(i(0<i<x)\) 满足 \(g(x)>g(i)\),则称 \(x\) 为反质数。
    • 例如,整数 \(1,2,4,6\)等都是反质数。
  • 现在给定一个数 \(N\) ,你能求出不超过 \(N\) 的最大的反质数么?

Input

  • 一个数\(N(1<=N<=2\times 10^9)\)

Output

  • 不超过 \(N\) 的最大的反质数。

Sample Input

1000

Sample Output

840

Hint

  • 保证 \(25\%\) 的数据 \(1<=N<=10^3\).
  • 保证\(50\%\) 的数据 \(1<=N<=1^5\).
  • 保证 \(75\%\) 的数据 \(1<=N<=10^8\).
  • 保证 \(100\%\) 的数据 \(1<=N<=2\times 10^9\).
  • 来源:\(luogup1463\)

分析

  • 先举个简单的例子,求一个数 \(756\) 的约数总个数。

    • 先将 \(756\) 分解质因子,得到 \(756=2^2×3^3×7^1\),再把三个指数加一连乘就是 \(756\) 约数的总个数:\((2+1)×(3+1)×(1+1)=24\)
  • 在本题中,所要求的是 \(1\sim N\) 范围内最大的反质数,实际上也就是要求约数个数最多的那个数。那么,一个数最多会有多少个不同的质因子呢?最多又会有多少个约数呢?

    • 粗略估算:\(2×3×5×7×11×13×17×19×23×29=6469693230>2×10^9\)。所以,我们就得到了一个很重要的性质:
      • 性质一:在 \(1\sim 2×10^9\) 中,一个数最多有 \(10\) 个不同的质因子。
      • 性质二:在 \(1\sim 2×10^9\) 中一个数其约数个数大致也就是 \(10^4\sim 10^5\) 级别。
    • 这两个性质虽然是通过估算得出的,但其正确性是无庸质疑的。在以后的算法设计中,这两个性质将起着举足轻重的作用。
  • 再回头看对正整数 \(756\) 的分析:\(756=2^2×3^3×7^1\) ,共有 \(24\) 个约数。那么它是否是一个“反质数”呢? 显然,我们可以构造出另一个正整数,也有 \(24\) 个约数,却比 \(756\) 要小:\(540=2^2×3^3×5^1\)

    • 构造反例的原理在于,\(756\) 的质因子 \(2,3,7\) 不是连续的质数,漏了 \(5\),用 \(5\) 代替 \(7\),而指数不变就可以构造出一个更小的但有着相同约数个数的正整数。因此,我们又得到了一个关于“反质数”的性质:
      • 性质三:一个反质数的质因子必然是从 \(2\) 开始连续的质数。
    • 分析至此,对“一个数和其约数”,“反质数”我们已有了初步的了解,并且大致掌握了一些基础性质。下面,在这些分析的基础上,我们开始尝试着设计一个时间效率上能够被接受的算法。
  • 算法设计

    • 由于题目中 \(N\) 的范围很大——有 \(2×10^9\),所以想通过求出每个数约数的个数,最后通过统计找出最大的反质数,这种方法效率很低,是不现实的。我们必须另辟蹊径。
    • \(1\sim 2×10^9\) 中有很多数显然不是“反质数”,在先前的分析中,性质三就充分说明了这一点。
    • 根据题目对“反质数”的定义,我们知道,不可能有两个反质数,其约数个数相同。那么,根据性质二,“反质数”的个数将远远小于 \(2×10^9\),而只是 \(10^4\)\(10^5\) 级别。这样一来,我们就可以考虑直接产生所有的“反质数”,再从中找出最大的。
    • 在先前的题意分析中,我们知道:“反质数”与一个数的约数总数,质因子总数都有着莫大的联系,不妨将这个因素放在一起。
    • \(f[i][j]\) 记录的是:约数总数为 \(i\),有 \(j\) 个不同的质因子的最小正整数。
    • 还是举个简单例子,\(f[12][3]=60,60=2^2×3^1×5^1\)。而 \(f[6][2]=12=2^2×3^1\) ,即:\(f[12][3]=f[6][2]×5\)
    • 状态转移方程:假设 \(p[j]\) 记录的是第 \(j\) 大的质数。
      • $ f[i][j]=min(f[\frac{i}{k+1}][j-1]*p[j]^k)$ 其中 \(i\ mod\ (k+1)==0,p[j]^k<=N\)
    • 边界条件:$ f[1][0]=1$ 。
    • 以质因子个数 \(j\) 为阶段。根据性质二,参数 \(i\) 的范围不超过是\(10^5\),参数 \(j\) 的范围不超过 \(10\)。所以,算法的空间复杂度还是可以承受的,不超过 \(O(sqrt(N)log2N)\)。在状态转移中,由于有 \(p[j]^2<=N\),所以 \(k\) 不会超过 \(log2N\),因此,算法的时间复杂度不超过 \(O(sqrt(N)(log2N)^2)\) 也是可以被接受的。
  • 方法二:

    • 由于\(2*3*5*7*11*13*17*19*23*29>2*10^9\) ,所以可以通过搜索枚举约数
    • 如果反素数 \(n=p_1^{a_1}*p_2^{a_2}*...*p_n^{a_n}\),它的约束个数为 \((a_1+1)*(a_2+1)*...*(a_n+1)\) ,而且我们很容易知道 \(a_1>=a_2>=a_3>=...>=a_n\) 。所以通过搜索枚举各素约数的个数很快就能过了。。。。。
posted @ 2020-07-30 11:58  ♞老姚♘  阅读(293)  评论(0编辑  收藏  举报