数论:质数与约数

摘自《算法竞赛进阶指南》。

数论

1.质数

质数的判定

试除法

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

 

质数的筛选

(1).Eratosthenes筛法

void primes(int n){
    memset(v,0,sizeof(v));//合数标记

    for(int i=2;i<=n;i++){
        if(v[i])continue;
        cout<<i<<endl;//i是质数

        for(int j=i;j<=n/i;j++)
            v[i*j]=1; 
    } 
}

 

(2).线性筛法

int v[N],prime[N];
void primes(int n){
    memset(v,0,sizeof(v));//最小质因子
    m=0;//质数数量

    for(int i=2;i<=n;i++){
        if(v[i]==0){//i是质数
            v[i]=i;
            prime[++m]=i; 
        }
        //给当前的数i乘上一个质因子

        for(int j=1;j<=m;j++){
        //i有比prime[j]更小的质因子,或者超出n的范围
            if(prime[j]>v[i]||prime[j]>n/i)
                break;

            //prime[j]是合数i*prime[j]的最小质因子
            v[i*prime[j]]=prime[j]; 
        } 
    } 

    for(int i=1;i<=m;i++)
        cout<<prime[i]<<endl;
}



质因数分解

(1).算数基本定理:任何一个大于1的正整数都能唯一分解为有限个质数的乘积

(2).试除法

void divide(int n){
    m=0;

    for(int i=2;i<=sqrt(n);i++)
        if(n%i==0){//i是质数
            p[++m]=i,c[m]=0;
            while(n%i==0)n/=i,c[m]++;//除掉所有的i 
        }
    }
 
if(n>1)//n是质数 p[++m]=n,c[m]=1; for(int i=1;i<=m;i++) cout<<p[i]<<'^'<<c[i]<<endl; }

 

2.约数

求N的正约数集合:试除法

int factor[1600],m=0;
for(int i=1;i*i<=n;i++){
    if(n%i==0){
        factor[++m]=i;
        if(i!=n/i)
            factor[++m]=n/i;
    }
}

for(int i=1;i<=m;i++)
    cout<<factor[i]<<endl;

 

求1~N每个数的正约数集合:倍数法

vector<int>factor[500010];
for(int i=1;i<=n;i++)
    for(int j=1;j<=n/i;j++)
        factor[i*j].push_back(i);

for(int i=1;i<=n;i++){
    for(int j=0;j<factor[i].size();i++)
        printf("%d ",factor[i][j]);
    puts("");
}

 

 

最大公约数

定理:gcd(a,b)*lcm(a,b)=a*b

 

九章算术·更相减损术

(1).gcd(a,b)=gcd(b,a-b)=gcd(a,a-b)

(2).gcd(2a,2b)=2gcd(a,b)

 

欧几里得算法:gcd(a,b)=gcd(b,a mod b)

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

 

互质与欧拉函数

互质:gcd(a,b)=1

欧拉函数:φ(N)
N=p1c1p2c2...pmcm
φ(N)=N((p1-1)/p1)((p2-1)/p2)...((pm-1)/pm)

int phi(int n){
    int ans=n;

    for(int i=2;i<=sqrt(n);i++)
        if(n%i==0){
            ans=ans/i*(i-1);
             while(n%i==0)n/=i;
        }

    if(n>1)ans=ans/n*(n-1);
    return ans;
}

 

性质1~2
(1).n>1,1~n中与n互质的数的和为nφ(n)/2
(2).若gcd(a,b)=1,则φ(ab)=φ(a)φ(b)

积性函数:若gcd(a,b)=1,有f(ab)=f(a)*f(b),那么称函数f为积性函数

性质3~6

(3).f(n)=f(p1c1)f(p2c2)...f(pmcm)
(4).若p|n且p2|n,则φ(n)=φ(n/p)*p
(5).若p|n但p2|n,则φ(n)=φ(n/p)*(p-1)
(6).Σd|nφ(d)=n

以上结论均不给出证明。

posted @ 2019-11-07 11:00  小仙女本仙  阅读(293)  评论(0编辑  收藏  举报