质数与约数

什么是质数

在大于1的整数中,约数只有1和本身,那么这个数就是质数,或者叫素数。

质数的判定

  1. 试除法 O(sqrt(n)),当然对于约数是成对出现即(d, x/d), 因此对于最大的约数d满足 d <= sqrt(x), 考虑到sqrt每次都要去调用函数计算,因此可以s

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "strconv"
        "strings"
    )
    
    func main() {
        var reader = bufio.NewReader(os.Stdin)
        var n = readInt(reader)
        for i := 0; i < n; i++ {
            var num = readInt(reader)
            fmt.Println(okString(num))
        }
    }
    
    func okString(num int) string {
        if ok(num) {
            return "Yes"
        }
        return "No"
    }
    
    func ok(num int) bool {
        if num <= 1 {
            return false
        }
    
        for i := 2; i < num/i+1; i++ {
            if num%i == 0 {
                return false
            }
        }
        return true
    }
    
    func readLine(reader *bufio.Reader) string {
        var line, _ = reader.ReadString('\n')
        return strings.TrimRight(line, "\n")
    }
    
    func readInt(reader *bufio.Reader) int {
        var a, _ = strconv.Atoi(readLine(reader))
        return a
    }
    
    func readArray(reader *bufio.Reader, sep string) []int {
        var line = readLine(reader)
        var strList = strings.Split(line, sep)
        var nums = make([]int, 0)
        var err error
        var v int
        for i := 0; i < len(strList); i++ {
            if v, err = strconv.Atoi(strList[i]); err != nil {
                continue
            }
            nums = append(nums, v)
        }
        return nums
    }

分解质因数

  1. 试除法分解质因数 O(sqrt(n));O(logn) ~ O(sqrt(n))

筛质数

朴素筛法

对于质数cnt++,对于每个数,将其倍数即为非质数

埃氏筛法

由算术基本定理,只需要筛除质数的倍数元素即可。就是说对于非质数continue,对于质数那么则需要标记其倍数为非质数。

线性筛法

对于一个非质数只会被它的最小质因子筛掉

什么是约数

一个数x的约数指的是可以被x整除的数

约数个数:对于一个数N=(p1^a1) * (p2^a2) * ... * (pk^ak),他的约数个数为(a1+1)*(a2+1)*...*(ak+1),它的各约数的和为(p1^0 + p1^1 + ... + p1^a1) + ... + (pk^0 + pk^1 + ... + pk^ak)

一个数的所有约数

试除法求一个数的约数

最后更新于

这有帮助吗?