反质数
反质数( 数学\(\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\) 级别。
- 这两个性质虽然是通过估算得出的,但其正确性是无庸质疑的。在以后的算法设计中,这两个性质将起着举足轻重的作用。
- 粗略估算:\(2×3×5×7×11×13×17×19×23×29=6469693230>2×10^9\)。所以,我们就得到了一个很重要的性质:
-
再回头看对正整数 \(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\) 开始连续的质数。
- 分析至此,对“一个数和其约数”,“反质数”我们已有了初步的了解,并且大致掌握了一些基础性质。下面,在这些分析的基础上,我们开始尝试着设计一个时间效率上能够被接受的算法。
- 构造反例的原理在于,\(756\) 的质因子 \(2,3,7\) 不是连续的质数,漏了 \(5\),用 \(5\) 代替 \(7\),而指数不变就可以构造出一个更小的但有着相同约数个数的正整数。因此,我们又得到了一个关于“反质数”的性质:
-
算法设计
- 由于题目中 \(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\) 。所以通过搜索枚举各素约数的个数很快就能过了。。。。。
hzoi