zoukankan      html  css  js  c++  java
  • 数论

    前置知识:

    a|b(“|”是整除符号),读作“a整除b”或“b能被a整除”。a叫做b的约数(或因数),b叫做a的倍数。

    质数 是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

    (1)判定——试除法

    遍历查找,能否找到一个值为2~n-1的i,且i|n, 即i整除n;

    bool is_prime(int n) {
    	if (n < 2) return false;
    	for (int i = 2; i < n; i++)
    		if (n % i == 0) return false;
    	return true;
    }
    

    试除法优化

    假设d能整除n,则有(n / d)能整除n,而我们只需要找到一个

    for (int i = 2; i <= n / i; i++)
    

    i * i <= n 可能会出现溢出(i+1)*(i+n) > int_max的情况,溢出为负值会影响判断。

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

    (2)分解质因数——试除法

    1. 暴力做法

    i为什么一定是质数?因为当循环经历过i=2之后则i的倍数均不可能满足

    void divide(int n) {
        for (int i = 2; i <= n; i++) {
            if (n % i == 0) { // i 一定是质数
                int sum = 0;
                while (n % i == 0) {
                    n /= i;
                    sum++;
                }
                printf("%d %d
    ", i, sum);
            }
        }
    }
    

    时间复杂度优化

    void divide(int n) {
        for (int i = 2; i <= n / i; i++) {
            if (n % i == 0) { // i 一定是质数
                int sum = 0;
                while (n % i == 0) {
                    n /= i;
                    sum++;
                }
                printf("%d %d
    ", i, sum);
            }
        }
        if (n > 1) printf("%d %d
    ", n, 1);
        puts("");
    }
    

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

    (3)筛质数

    算数基本定理

    算术基本定理可表述为:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积

    事件复杂度O(nlogn) 1~n中有(n/log{n}) 个质数

    int primes[N], cnt;
    bool st[N];
    
    void get_primes(int n) {
        for (int i = 2; i <= n; i++) {
            if (!st[i]) {
                primes[cnt++] = i;
            }
            for (int j = i + i; j <= n; j += i) 
                st[j] = true;
        }
    }
    

    优化后,埃氏筛法

    int primes[N], cnt;
    bool st[N];
    
    void get_primes(int n) {
        for (int i = 2; i <= n; i++) {
            if (!st[i]) {
                primes[cnt++] = i;
                for (int j = i + i; j <= n; j += i) 
                st[j] = true;
            }
        }
    }
    

    线性筛法

    核心:n只会被它的最小质因子筛掉

    void get_primes(int n) {
        for (int i = 2; i <= n; i++) {
            if (!st[i]) {
                primes[cnt++] = i;
            }
            for (int j = 0; primes[j] <= n / i; j++) {
                st[primes[j] * i] = true;
                if (i % primes[j] == 0) break; // primes[j] 是i的最小质因子
            }
        }
    }
    

    对于任意一个合数x,在x/pj时就会被筛掉

    2. 约数

    (1)试除法求一个数的所有约数

    (2)约数个数

    int范围内,约数最多为1500个

    (3)约数之和

    例题:约数个数

    约数之和

    (4)欧几里得算法(辗转相除法

    核心公式:

    代码:


    3. 欧拉函数

    欧拉函数定义:1~n中互质的数的个数

    image-20200920234303419

    则有如下公式:

    image-20200920234508486

    可以利用容氏原理来证明

  • 相关阅读:
    Python基础知识
    Oracle 总结
    Linux基本命令
    测试理论
    计算机基础
    http常见的状态码,400,401,403状态码分别代表什么?
    html
    day21 包
    day20 模块引入的一些说明
    我又回来了???
  • 原文地址:https://www.cnblogs.com/mayapony/p/13996407.html
Copyright © 2011-2022 走看看