算法数论(质数和约数)

数论1(指数和约数).算法

0.算术基本定理

这是基础,先掌握
在这里插入图片描述

1.质数

1.1试除法判断质数(O(sqrt(n))

1不是质数, 根据性质,在2 ~sqrt(x)中,若有x可以整除的数则不是质数。

模板

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

1.2试除法求质因子

题目:给定 n𝑛 个正整数 𝑎𝑖,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。

①:x中至多只有一个大于根号n的因数;反证法:若有两个则a1 * a2大于n,不满足因数乘积小于等于n

②:i一定是质数。反证法:假如 i 是一个合数,那么它一定可以分解成多个质因子相乘的形式,这多个质因子同时也是 a 的质因子且比 i 要小,而比 i 小的数*在之前的循环过程中一定是被条件除完了的*,所以 i 不可能是合数,只可能是质数

特判大于根号n的质因数

#include <bits/stdc++.h>
using namespace std;
int n, a;

int divide(int x){
    for(int i = 2; i <= x/i; i ++){//①
        if(x % i == 0){//②
            int t = 0;//指数
            while(x % i == 0) x = x / i, t ++;//找x里面有几个i
            cout << i << " " << t<<endl;
        }
    }
    if(x > 1) cout << x << " "<< 1<<endl;//③
    cout << endl;
}

int main(){
    cin >> n ;
    while(n --){
        cin >> a;
        divide(a);
    }
    return 0;
}

1.3筛质数

埃氏筛法

筛掉倍数 例如一组数:2 3 4 5 6 7 8 9

4 6 8 9都是前面的倍数,故若p不被筛掉,则2~ p-1中无p的因数,所以p是质数;所以剩下的是质因数

`

int get_prime(){
    for(int i = 2; i <= n; i ++){
        if(!st[i]){
            p[cnt++] = i;//记录质数
            for(int j = i; j <= n; j+=i) st[j] = true;//标记筛掉的数
        }
    }
    return cnt;
}

`

2.约数

2.1试除法求约数O(n*根号n)

求x的所有约数,即能被x整除的数;如果i是x的约数,那么n/i也必为x的约数。从而得到了优化。即只要循环遍历1-n/i的数


vector<int> get_divisors(int x){
    vector<int> res;
    for(int i = 1; i <= x/i ; i ++){
        if(x%i == 0){
            res.push_back(i);
            if(i != x/i) res.push_back(x/i);//去重
        }
    }
    sort(res.begin(), res.end());
    return res;
}

2.2约数个数

约数个数:若干质因子次方加一的乘积。

思路:用哈希表存储质因子和指数。最后遍历结果。

​ 存储质因子时用上面的试除法。。。

******一个小知识:在int范围内,最多的约数个数大概为1500个

由算术基本定理,每一个数都可以写成若干质因子次方乘积。如下图:

在这里插入图片描述

在这里插入图片描述

约数个数:若干质因子次方加一的乘积。

证明省略,详见y总–证明

例题:

给定 𝑛 个正整数 𝑎𝑖,请你输出这些数的乘积的约数个数,答案对 1e9+7 取模。

输入格式

第一行包含整数 𝑛。

接下来 𝑛 行,每行包含一个整数 𝑎𝑖。

输出格式

输出一个整数,表示所给正整数的乘积的约数个数,答案需对 10e9+7 取模。

#include <bits/stdc++.h>
using namespace std;
const int M = 1e9 + 7;
typedef long long ll;
int n, x;

int main(){
    cin >> n;
    
    unordered_map<int,int> primes;//存放质因数即指数
    while(n --){
        cin >> x;
        for(int i = 2; i <= x/i; i ++){//试除法因式分解
            while(x % i == 0){
                x /= i;
                primes[i]++;
            }
        }
        if(x > 1) primes[x] ++;//特判 最多出现一个大于根号x的质数(前面有证明)
    }
    ll res = 1;
    for(auto prime : primes) res = res * (prime.second + 1) % M;//结论直接用
    cout << res;
    return 0;
}

2.3约数之和

在这里插入图片描述

考虑一个质因数p的e次方的所有约数之和:在这里插入图片描述

那么多个,则为所有可能情况的乘积:在这里插入图片描述

例题:题解

给定 𝑛 个正整数 𝑎𝑖,请你输出这些数的乘积的约数之和,答案对 1e9+7 取模。

输入格式

第一行包含整数 𝑛。

接下来 𝑛 行,每行包含一个整数 𝑎𝑖。

输出格式

输出一个整数,表示所给正整数的乘积的约数个数,答案需对 10e9+7 取模。

关键部分,求各部分的

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
const int M = 1e9 + 7;
typedef long long ll;
int n, x;

int main(){
    cin >> n;
    
    unordered_map<int,int> primes;//存放质因数即指数
    while(n --){
        cin >> x;
        for(int i = 2; i <= x/i; i ++){//试除法因式分解
            while(x % i == 0){
                x /= i;
                primes[i]++;
            }
        }
        if(x > 1) primes[x] ++;//特判 最多出现一个大于根号x的质数(前面有证明)
    }
    ll res = 1;
    for(auto prime : primes){
        int p = prime.first, a = prime.second;
        ll t = 1;
        while( a--){
            t = (t*p + 1) %M;//求每一部分的和
        }
        res = res * t % M;//乘入结果
    }
    cout << res;
    return 0;
}

2.4欧几里得(辗转相除法)求最大公约数

整除与除以的区别:24 ÷ 6 = 4指24能被6整除; 24 除以 6 等于4

内容:较大数除以较小数得到商和余数,再用除数和余数反复做除法运算,当余数为0时,取当前算式除数为最大公约数。

证明:

a, b(a> b)

a = b* q + r(q 为商, r 为余数)

设 d是a, b的一个公约数,那么a = md, b = nd;

带入 md = nd*q + r; r = (m - nq) * d.即d也是r 的一个约数。

所以求a, b的最大公约数即求 b, r的最大公约数

gcd(a,b) = gcd(b, amod b)

法一:公式__gcd(a,b)

c++自带函数1122ms, 比赛时省事就直接用函数吧。。。。。

法二:自写函数gcd(a,b)

1156ms


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

r = (m - nq) * d.即d也是r 的一个约数。

所以求a, b的最大公约数即求 b, r的最大公约数

gcd(a,b) = gcd(b, amod b)

法一:公式__gcd(a,b)

c++自带函数1122ms, 比赛时省事就直接用函数吧。。。。。

法二:自写函数gcd(a,b)

1156ms


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

作者: 裴定一 / 祝跃飞 出版社: 科学出版社 出版年: 2002年09月 页数: 233 页 定价: 19.00 装帧: 平装 ISBN: 9787030106834 内容简介 · · · · · · 本书论述了算法数论的基本内容,其中包括:连分数、代数数域、椭圆曲线、素性检验、大整数因子分解算法、椭圆曲线上的离散对数、超椭圆曲线。本书的特点是内容涉及面广,在有限的篇幅内,包含了必要的预备知识数学证明,尽可能形成一个完整的体系。并且本书的部分内容曾多次在中国科学院研究生院信息安全国家重点实验室广州大学作为硕士研究生教材使用。 本书可作为信息安全、数论等专业的研究生教材及相关专业的研究人员、高等学校的教师高年级学生的参考。 序 前言 第一章 整数的因子分解 1.1 唯一分解定理 1.2 辗转相除法(欧氏除法) 1.3 Mersenne素数Fermat素数 1.4 整系数多项式 1.5 环Z[i]Z[ω] 习题一 第二章 同余式 2.1 孙子定理 2.2 剩余类环 2.3 Euler函数ρ(m) 2.4 同余方程 2.5 原根 2.6 缩系的构造 习题二 第三章 二次剩余 3.1 定义及Euler判别条件 3.2 Legendre符号 3.3 Jacobi符号 习题三 第四章 特征 4.1 剩余系的表示 4.2 特征 4.3 原特征 4.4 特征 4.5 Gauss 习题四 第五章 连分数 5.1 简单连分数 5.2 用连分数表实数 5.3 最佳渐近分数 5.4 Legendre判别条件 习题五 第六章 代数数域 6.1 代数整数 6.2 Dedekind整环 6.3 阶的一些性质 第七章 椭圆曲线 7.1 椭圆曲线的群结构 7.2 除子类群 7.3 同种映射 7.4 Tate模Weil对 7.5 有限域上的椭圆曲线 习题七 第八章 在密码学中的一些应用 8.1 RSA公钥密码 8.2 Uiffie-Hellman体制 8.3 ElGamal算法 8.4 基于背包问题的公钥密码 8.5 秘密共享 第九章 素性检验 9.1 Fermat小定理及伪素数 9.2 强伪素数及Miller-Rabin检验 9.3 利用n-1的因子分解的素性检验 9.4 利用n+1的因子分解的素性检验 9.5 分圆环素性检验 9.6 基于椭圆曲线的素性检验 第十章 大整数因子分解算法 10.1 连分数因子分解算法 10.2 二次筛法 10.3 Pollard的P-1因子分解算法 10.4 椭圆曲线因子分解算法 10.5 数域筛法 习题十 第十一章 椭圆曲线上的离散对数 11.1 椭圆曲线公钥密码 11.2 小步-大步法 11.3 家袋鼠野袋鼠 11.4 MOV约化 11.5 FR约化 11.6 SSSA约化 11.7 有限域上离散对数的计算 第十二章 超椭圆曲线 12.1 超椭圆曲线的Jacobian 12.2 虚二次代数函数域 12.3 基于超椭圆曲线的公钥密码 附录 一些常用算法 A.1 不可约多项式的判别 A.2 有限域中平方根的求解 A.3 有限域上的分解 A.4 Hensel引理 A.5 格 A.6 Z[x]中多项式的分解 参考文献
内容简介: 本书论述了算法数论的基本内容,其中包括:连分数、代数数域、椭圆曲线、素性检验、大整数因子分解算法、椭圆曲线上的离散对数、超椭圆曲线。本书的特点是内容涉及面广,在有限的篇幅内,包含了必要的预备知识数学证明,尽可能形成一个完整的体系。并且本书的部分内容曾多次在中国科学院研究生院信息安全国家重点实验室广州大学作为硕士研究生教材使用。本书可作为信息安全、数论等专业的研究生教材及相关专业的研究人员、高等学校的教师高年级学生的参考。 目录: 序 前言 第一章 整数的因子分解 1.1 唯一分解定理 1.2 辗转相除法(欧氏除法) 1.3 Mersenne素数Fermat素数 1.4 整系数多项式 1.5 环ZZ[ω] 习题一 第二章 同余式 2.1 孙子定理 2.2 剩余类环 2.3 Euler函数ρ(m) 2.4 同余方程 2.5 原根 2.6 缩系的构造 习题二 第三章 二次剩余 3.1 定义及Euler判别条件 3.2 Legendre符号 3.3 Jacobi符号 习题三 第四章 特征 4.1 剩余系的表示 4.2 特征 4.3 原特征 4.4 特征 4.5 Gauss 习题四 第五章 连分数 5.1 简单连分数 5.2 用连分数表实数 5.3 最佳渐近分数 5.4 Legendre判别条件 习题五 第六章 代数数域 6.1 代数整数 6.2 Dedekind整环 6.3 阶的一些性质 第七章 椭圆曲线 7.1 椭圆曲线的群结构 7.2 除子类群 7.3 同种映射 7.4 Tate模Weil对 7.5 有限域上的椭圆曲线 习题七 第八章 在密码学中的一些应用 8.1 RSA公钥密码 8.2 Uiffie-Hellman体制 8.3 ElGamal算法 8.4 基于背包问题的公钥密码 8.5 秘密共享 第九章 素性检验 9.1 Fermat小定理及伪素数 9.2 强伪素数及Miller-Rabin检验 9.3 利用n-1的因子分解的素性检验 9.4 利用n+1的因子分解的素性检验 9.5 分圆环素性检验 9.6 基于椭圆曲线的素性检验 第十章 大整数因子分解算法 10.1 连分数因子分解算法 10.2 二次筛法 10.3 Pollard的P-1因子分解算法 10.4 椭圆曲线因子分解算法 10.5 数域筛法 习题十 第十一章 椭圆曲线上的离散对数 11.1 椭圆曲线公钥密码 11.2 小步-大步法 11.3 家袋鼠野袋鼠 11.4 MOV约化 11.5 FR约化 11.6 SSSA约化 11.7 有限域上离散对数的计算 第十二章 超椭圆曲线 12.1 超椭圆曲线的Jacobian 12.2 虚二次代数函数域 12.3 基于超椭圆曲线的公钥密码 附录 一些常用算法 A.1 不可约多项式的判别 A.2 有限域中平方根的求解 A.3 有限域上的分解 A.4 Hensel引理 A.5 格 A.6 Z[x]中多项式的分解 参考文献 免责申明:此书是我在网络上获取的,希望对大家有用。资源版权归作者及其公司所有,如果你喜欢,请购买正版。~~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值