Algorithm9.2 数论入门

[TOC]

数论基础

最大公约数gcd

int gcd(int a,int b) { return (b>0)?gcd(b, a%b):a; }

利用的就是欧几里得原理

int gcd(int a, int b) { return (b<=0)?a:gcd(b, a%b); }

最大公约数[gcd]与最小公倍数[gld]乘积 == 这两个数的乘积

a*b = gcd(a, b)*gld()

最小公倍数[gld]

可以利用最大公约数倒推回去,也就是gld(a, b)=a*b/gcd(a, b)

质数

判断1~n中的所有质数

1、基础:O(n^2)复杂度,遍历,遍历的边界从3~sqrt(x)

bool isprime(int x){
    for (int i = 3; i <= sqrt(x); ++i) if (x%i == 0) return false;
    return true;
}

2、埃拉托斯特尼筛:O(nlogn)复杂度

3、线性筛:O(n)

prime是质数列表,isprime

#define maxn 10000010
int vis[maxn], prime[maxn], isprime[maxn];

void Prime()
{
    for(int i=2; i<=b; i++)
    {
        if(!vis[i]) prime[cnt++] = i, isprime[i] = 1;
        for(int j=0; j<cnt&&i*prime[j]<=b; j++)
        {
            vis[i*prime[j]] = i;
            if(i%prime[j]==0) break;
        }
    }
}
b = 100; // 设置筛的边界
LPrime();
for (int i = 5; i < 20; ++i) {
    printf("%d %d %d\n", i, prime[i], isprime[i]); // prime是按照顺序的素数存放进来, isprime是索引的数是否为质数
}
Posted on Feb 1, 2021