• 数学知识之约数


    约数,又称因数,如果一个数 x 能被 k 整除( x 是 k 的整数倍),那么 k 就是 x 的一个约数。

    试除法求约数:

    如果一个数有约数,那么约数一定是成对出现的,一个大于等于sqrt(x),一个小于等于sqrt(x);

    若找到小于等于sqr(x)的约数,那么大于等于sqrt(x)的约数也被找到;

    只需枚举1~sqrt(x)内的所有数,就可以求出x的所有约数;

    时间复杂度为O(sqrt(n))。

    1.代码模板如下:

    1. void get_divisors(int x) {
    2. for (int i = 1; i <= x / i; i++) {
    3. if (x % i == 0) {//发现约数
    4. res[cnt++] = i;//i为约数
    5. if (x / i != i)res[j++] = x / i;//x/i也为约数
    6. //注意如果等于sqrt(x)的话就只有一个约数
    7. }
    8. }
    9. }

    求约数个数:

    求一个数有多少个个约数,先将该数进行质因数分解

    数学知识之质数_如何何何的博客-CSDN博客

    a = p1^α1 * p2^α2 * …… * pn^αn

    约数个数就等于:

    cnt = (α1+1) * (α2+1*) * …… * (αn+1)

    注意:1需要特判,1不能被分解为质数,但约数个数为一。

    1.代码模板如下:

    1. void cnt_divisors(int x) {
    2. unordered_map<int, int>primes;//存储质因数分解的结果
    3. //分解质因数
    4. for (int i = 2; i <= x / i; i++) {
    5. if (x % i == 0) {
    6. while (x % i == 0) { primes[i]++; x /= i; }
    7. }
    8. }
    9. if (x > 1)primes[x]++;
    10. int res = 1;
    11. for (auto i = primes.begin(); i != primes.end(); i++)//遍历unordered_map
    12. res = (res * (i->second + 1)) % mod;//结果余上mod
    13. return;
    14. }

    2.拓展,一个数的约数个数为3说明:

    该数的约数为1,sqrt(x),x,且sqrt(x)为质数。

    求约数之和:

    求一个数的所有约数的和,同样先将该数进行分解质因数操作:

    a = p1^α1 * p2^α2 * …… * pn^αn

    约数之和就等于:

    cnt = (p1^0 + p1^1 + …… + p1^α1) * (p2^0 + p2^1 + …… + p2^α2) *……* (pn^0 + pn^1 + …… + pn^αn)

    1.代码模板如下:

    1. void add_divisors(int x) {
    2. unordered_map<int, int>primes;//存储质因数分解的结果
    3. //分解质因数
    4. for (int i = 2; i <= x / i; i++) {
    5. if (x % i == 0) {
    6. while (x % i == 0) { primes[i]++; x /= i; }
    7. }
    8. if (x > 1)primes[x]++;
    9. }
    10. long long res = 1, tmp, cur;
    11. for (auto i = primes.begin(); i != primes.end(); i++) {//遍历所有质因数
    12. int a = i->first, p = i->second;//a^p
    13. cur = 1, tmp = a;
    14. while (p--) {
    15. cur = (cur + a) % mod;
    16. a = a * tmp % mod;
    17. }
    18. res = res * cur % mod;
    19. }
    20. return ;
    21. }

    求最大公约数

    使用欧几里得算法求最大公约数,也叫做辗转相除法。

    a,b 的最大公约数等价于 b,a%b 的最大公约数。当 b(a%b) 等于 0 时,a 就是最大公约数。


     

    1.代码模板如下:

    1. int gcd(int a, int b) {
    2. return b ? gcd(b, a % b) : a;
    3. }

  • 相关阅读:
    Java 反射的应用 - 对象转Map
    SpringMVC:RESTful案例
    【C++】基础容器(学习笔记)
    重采样原理及仿真
    2022-03-01-SpringMVC
    阿里云通用算力型u1云服务器配置性能评测及价格参考
    mybatis 数据库字段为空or为空串 忽略条件过滤, 不为空且不为空串时才需nameParam过滤条件
    专利申请的流程与时间
    FCN的代码解读
    一种有效的并行进化元启发法及其在三个优化问题中的应用
  • 原文地址:https://blog.csdn.net/weixin_56265979/article/details/127984400