zoukankan      html  css  js  c++  java
  • 反质数

    反质数( 数学(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 imes 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 imes 10^9).
    • 来源:(luogup1463)

    分析

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

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

      • 粗略估算:(2×3×5×7×11×13×17×19×23×29=6469693230>2×10^9)。所以,我们就得到了一个很重要的性质:
        • 性质一:在 (1sim 2×10^9) 中,一个数最多有 (10) 个不同的质因子。
        • 性质二:在 (1sim 2×10^9) 中一个数其约数个数大致也就是 (10^4sim 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),所以想通过求出每个数约数的个数,最后通过统计找出最大的反质数,这种方法效率很低,是不现实的。我们必须另辟蹊径。
      • (1sim 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) 。所以通过搜索枚举各素约数的个数很快就能过了。。。。。
  • 相关阅读:
    (原创)在ER/Studio中使用宏把Attribute name复制到Definition
    Xming + PuTTY 在Windows下远程Linux主机使用图形界面的程序
    一个时间日期转换格式的小功能(Oracle)
    C#正则表达式整理备忘【转】
    【转】一篇好文,以在迷茫时阅读
    经常关注的、极具参考价值的网站收集(无限畅想版)
    中文分词备忘
    我心目中的编程高手
    网站推荐
    通过手机短信控制电脑
  • 原文地址:https://www.cnblogs.com/hbhszxyb/p/13402992.html
Copyright © 2011-2022 走看看