因为以前从来没接触过数论,小学也没搞过奥数,而且数论这东西又挺重要的,不只是比赛,有些东西基本算是常识需要知道的。而且内容还很杂。所以决定好好写一篇博客,包括知识点和自己的理解。

目录

0.特殊性质

一.分解质因数和算术基本定理

如何分解质因数

二.判断素数 和素数筛(埃筛和欧拉筛)

素数判断

素数筛法

三.约数

一个数的所有约数

约数个数

约数之和

最大公约数GCD

四.欧拉函数和欧拉函数筛及欧拉定理

求一个数的欧拉函数

欧拉函数筛

欧拉定理

费马小定理


0.特殊性质

平常写题会碰到的一些特殊性质。

整除性质:

1、若b|a,c|a,且b和c互质,则bc|a。

2、对任意非零整数a,±a|a=±1。

3、若a|b,b|a,则|a|=|b|。

4、如果a能被b整除,c是任意整数,那么积ac也能被b整除。

5、如果a同时被b与c整除,并且b与c互质,那么a一定能被积bc整除,反过来也成立。

6、对任意整数a,b>0,存在唯一的数对q,r,使a=bq+r,其中0≤r<b,这个事实称为带余除法定理,是整除理论的基础。

7、公因数一定整除最大公因数。

8.d|a,d|b 则d|ax+by。

9.整除的传递性。若a|b b|c 则a|c。

1.定理:两数最大公约数与最小公倍数的积等于两数之积 

所以互质的两数乘积就是最小公倍数。

2.

一.分解质因数和算术基本定理

       ① 惟一分解定理 (算术基本定理) 可表述为:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。这样的分解称为 的标准分解式。

质因数素因数质因子)在数论里是指能整除给定正整数的质数。除了1以外,两个没有其他共同质因子的正整数称为互质。因为1没有质因子,1与任何正整数(包括1本身)都是互质。正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以用指数表示。根据算术基本定理,任何正整数皆有独一无二的质因子分解式  。只有一个质因子的正整数为质数。

如何分解质因数

分解质因数,也就是将n表示为标准分解式。所以我们要求出质因数和对应的指数。

试除法:

为什么只要枚举到sqrt(n)就行呢?

因为超过sqrt(n)的部分基本没有意义,因为如果存在多个大于sqrt(n)的质因数,根据惟一分解定理,n由这些数相乘组成,那么多个大于sqrt(n)的质因数相乘就超过了n,矛盾。

所以最多只会有一个大于sqrt(n)的质因数,所以当枚举到sqrt(n)时剩下的数不等于1,那么说明还剩下这个大于sqrt(n)的质因数。额外加上即可。

vector<pair<int,int>> div(int n){vector<pair<int,int>> ans;
//因为惟一分解定理,合数也是由多个质数组成,合因数组成的较小质数会被先分解,所以每次得到的必定是质因数for(int j=2;j<=n/j;j++){//除净小于sqrt(n)的质因数int sum=0;while(n%j==0){//除净质因数n/=j;sum++;//该质因数的指数}if(sum!=0)ans.push_back({j,sum});}if(n>1)//大于sqrt(n)的质因数只会有一个,如果有多个,分解定理的乘积就大于n了ans.push_back({n,1});return ans;
}unordered_map<int,int> div(int n){//得到质因数unordered_map<int,int>ans;for(int j=2;j<=n/j;j++){if(n%j==0){while(n%j==0){n/=j;ans[j]++;} }}if(n>1)ans[n]++;return ans;
}

参考:

数学数论相关 - ternary_tree 的博客 - 洛谷博客 (luogu.org)

二.判断素数 和素数筛(埃筛和欧拉筛)

素数判断

·        根据素数的定义,只含有1和本身的因数的数被称为素数,由此定义枚举小于这个数的所有数,如果出现能够整除的,说明这个数不是质数。

注意:此处只需要枚举到sqrt(k)。

因为 若 i | k,则 k/i | k

所以i如果不是因数,那么k/i也不是,最多到sqrt(k),超过这个范围就没有意义了。

O(sqrt(n))

此处两数相乘采用逆元,可以防止爆int

int is_prime(int k) {//判断k是否是质数int ok = 1;if (k < 2)return 0;for (int j = 2; j <= k / j; j++) {//枚举到sqrt(k)if (k % j == 0) {ok = 0;return 0;}}return 1;
}

素数筛法

P3383 【模板】线性筛素数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

        1.埃筛的思想比较简单,一个数的所有倍数都不可能是质数所以,枚举当前数的范围内所有倍数,将他们删去,剩下的都是质数。同时可以简单优化一下,由惟一分解定理,只需要筛去质数,合数也就会被顺带筛去。所以枚举质数的倍数即可。优化后复杂度O(nloglog)

        2.欧拉筛也叫做线性筛。他保证每次筛的时候只会通过一个质因数将一个合数筛去,而不像埃筛那样重复筛同一个数好多次。

其主要的优化有两方面:

①每次只枚举质数的倍数。

保证prime[i]是某个被筛去的合数的最小质因数.

重点在第二点。因为我们是从小到大枚举的质数,那么当第一次满足判断的数j,j%prime[i]==0那么这个prime[i]就是j的最小质因数,同时也是prime[i]*j的最小质因数。同时,因为prime[i]是j的最小质因数,那么prime[i]也会是之后prime[i+1~size]*j这些合数的最小质因数。

原理:欧拉筛筛素数 - 学委 的博客 - 洛谷博客 (luogu.com.cn)

#include<bits/stdc++.h>
using namespace std;
#pragma warning(disable:4996);
//#define int long long
#define rep(j,b,e) for(int j=(b);j<=(e);j++)
#define drep(j,e,b) for(int j=(e);j>=(b);j--)
const int N = 1e8 + 10;
int T = 1;
int n, m, k;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);
}
vector<int>prime;
int NotisPrime[N];//1表示不是一个质数
void GetPrime_Era(int n) {//会多次标记同一个值rep(j, 2, n) {if (NotisPrime[j] == 0) {//如果是质数prime.push_back(j);for (int i = j; i <= n/j; i++)//质数的倍数全是合数,逆元写成/j防止爆intNotisPrime[i * j] = 1;}}
}
void GetPrime_Ola(int n) {//效率更高,一个数只会被他的最小质因数筛掉rep(j, 2, n) {if (NotisPrime[j] == 0)//筛完还是素数就加入prime.push_back(j);for (int i = 0; i < prime.size() && prime[i] <= n/j; i++) {//逆元枚举质数,筛pi*jNotisPrime[j * prime[i]] = 1;if (j % prime[i] == 0)break;//保证prime[i]是这个合数的最小质因数}}
}
signed main() {
#ifndef ONLINE_JUDGEfreopen("out.txt", "w", stdout);
#endifios::sync_with_stdio(0); cout.tie(0);int q;cin >> n >> q;GetPrime_Ola(n);rep(j, 1, q) {cin >> k;cout << prime[k - 1] << endl;}
}

三.约数和公约数

一个数的所有约数

试除法

枚举到sqrt(n) ,原理同判断质数。

vector<int> div(int k){vector<int>ans;for(int j=1;j<=k/j;j++){if(k%j==0){ans.push_back(j);if(j!=k/j)ans.push_back(k/j);}}sort(ans.begin(),ans.end());//k的约数约有log个return ans;
}

约数个数

870. 约数个数 - AcWing题库

本题是求一个很大乘积的约数,而这个很大的数不比表示出来,他的标准分解式就等于每个乘数的标准分解式的乘积。

由算术基本定理:

N=

一个数的约数个数 sum= ,也就是质因数指数+1的乘积。

因为算术基本定理,里面的质因数随意组合得到的数都是N的约数,每个质因数有0-ai种选法,由乘法原理,总的选择数为指数+1的乘积。

做法:

先对数N进行质因数分解,求出质因数和对应指数,然后求指数+1的乘积即可。

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9 +7;
int main(){int n;cin>>n;unordered_map<int,int>prime;//质因数和指数while(n--){int k;cin>>k;for(int j=2;j<=k/j;j++){//分解质因数得到底数和指数while(k%j==0){k/=j;prime[j]++;}}if(k>1)prime[k]++;}long long  ans=1;for(auto [p,cnt]:prime){ans=(ans*(cnt+1))%mod;//约数个数等于分解式的所有指数+1的乘积}cout<<ans<<endl;
}

约数之和

871. 约数之和 - AcWing题库

根约数个数的推导类似,所有质因数及其指数的排列组合构成所有的因数,所以约数和就是将每种组合都列出来然后相加,而提取公因式后可以得到

sum=

也就是所有质因数的所有指数的和的乘积

所以做法和约数个数很像,先分解质因数求出质因数和指数,然后写出公式。

这里求一个质因数的所有指数的和有个简便方法。

迭代 t=p*t+1

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9 +7;
int main(){int n;cin>>n;unordered_map<int,int>prime;//质因数和指数while(n--){int k;cin>>k;for(int j=2;j<=k/j;j++){//分解质因数得到底数和指数while(k%j==0){k/=j;prime[j]++;}}if(k>1)prime[k]++;}long long  ans=1;for(auto [p,cnt]:prime){long long t=1;while(cnt--)t=(p*t+1)%mod;//质因数所有指数的和ans=(ans*t)%mod;//求积}cout<<ans<<endl;
}

最大公约数GCD

辗转相除法:

如果

 且  则有

所以对于A和B的最大公约数,则会满足   用取模加快减法运算

得到

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

裴蜀定理

  是不全为零的整数,则存在整数 , 使得 .

且gcd(a,b)是能得到的最小值,其他值全是gcd的倍数。

扩展欧几里得算法

877. 扩展欧几里得算法 - AcWing题库

扩展欧几里得算法是用来求解裴蜀定理中的x和y的。

好烦不会证明qwq

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;
//a*b+b*y=gdc(a,b)
int exgcd(int a,int b,int& x,int& y){if(b==0){x=1,y=0;return a;}int res=exgcd(b,a%b,y,x);y-=a/b*x;return res;
}
int main()
{int n;cin>>n;while (n -- ){int a,b,x,y;cin>>a>>b;exgcd(a,b,x,y);cout<<x<<" "<<y<<endl;}
}

线性同余方程

878. 线性同余方程 - AcWing题库

线性同余方程:

由扩展欧几里得,可得

的x,

又因为gcd(a,p) | (ax+by)

所以,如果b是gcd(a,p)的倍数,方程有解且解为方程倍,反之无解。

所以先用gcd判断有解后,使用扩展欧几里得算法得到,然后扩大倍即可

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;int n;
int a,b,p;
int exgcd(int a,int b,int &x,int &y){if(b==0)//mod等于0相当于整除{//a*1+b*0=ax=1,y=0;return a;}int d=exgcd(b,a%b,y,x);y-=a/b*x;return d;
}
int main()
{cin >> n;while (n -- ){cin>>a>>b>>p;int x,y;int d=exgcd(a,p,x,y);//a*x=p*y+bif(b%d)cout<<"impossible"<<endl;else{x=(LL)x*(b/d)%p;cout<<x<<endl;}}
}

四.欧拉函数和欧拉函数筛及欧拉定理

求一个数的欧拉函数

873. 欧拉函数 - AcWing题库

 与N互质的数的个数称为N的欧拉函数,记做phi[N]

欧拉函数值可以通过上表的公式得到,可以看到N的欧拉函数只与质因数有关,和指数无关。

证明依靠容斥定理,略。

可以做法就是先求出N的所有质因数,然后带入公式

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
unordered_map<int,int> div(int n){//得到质因数unordered_map<int,int>ans;for(int j=2;j<=n/j;j++)if(n%j==0)while(n%j==0){n/=j;ans[j]++;} if(n>1)ans[n]++;// 惟一一个大于sqrt(n) 的质因数不要遗漏return ans;
}
int main()
{int n;cin >> n;while (n -- ){int k;cin >> k;auto ans=div(k);int res=k;for(auto&[prime,cnt]:ans){res=res/prime*(prime-1);//带入公式,注意都是整除。可以先除prime,因为prime是质因数,N能正常prime,然后再乘prime-1保证精度不丢失}cout<<res<<endl;}
}

欧拉函数筛

874. 筛法求欧拉函数 - AcWing题库

可以根据线性筛的思路,得到质数,根据质数作为某个数的质因数进行筛。

根据公式可以推出,

①j为质数数,欧拉函数ola[j]=j-1,因为质数的质因子只有他本身,也可以认为质数之前的所有数都和他自己互质(公约数只为1)

②pi为质数,j为任意数,且pi是j的质因子

根据欧拉公式,pi*j和 j 的质因数无差别,只有pi的指数有差别欧拉函数和质因子指数无关,所有欧拉函数的差别仅在N上。

易得 ola[pi*j]=pi*ola[j]

③pi为质数,j为任意数,且pi不是j的质因子

根据欧拉公式,pi*j和j的标准分解式差距只在pi*j多一个pi。带入欧拉公式

多一个pi*(pi-1)/pi=pi-1

易得 ola[pi*j]=(pi-1)*ola[j]

#include <bits/stdc++.h>using namespace std;
int n;
const int N = 1e6+10;
vector<int>prime;
int NotIsPrime[N];
long long ola[N];
long long get_ola(int n){ola[1]=1;//1的欧拉函数为1for(int j=2;j<=n;j++){if(NotIsPrime[j]==0){prime.push_back(j);ola[j]=j-1;//质数前面的所有数都与他互质}for(int i=0;i<(int)prime.size() and prime[i]<=n/j;i++){NotIsPrime[prime[i]*j]=1;if(j%prime[i]==0){ola[j*prime[i]]=prime[i]*ola[j];//pi是j的最小质因数,欧拉函数和质因数指数无关,大小只变化pi倍break;}else{ola[j*prime[i]]=ola[j]*(prime[i]-1);;//*prime[i]-1;//根据欧拉函数公式,乘上非质因数之后变化pi*((pi-1)/pi),也就是pi-1倍}}}return accumulate(ola,ola+n+1,0ll);
}
int main()
{cin>>n;cout<<get_ola(n);
}

欧拉定理

若 a和b互质,则 

证明:

为与b互质的数的集合。

给集合每个数乘上一个a得到集合

,集合元素相乘,提取a,同时mod b

消去相同部分

费马小定理

由欧拉定理,当b为质数时phi[b]=b-1

五.快速幂

快速幂的本质思路还是倍增,将幂表示为二进制即用二进制表示所有数。

例如3^5,5的二进制 101,可以看作2^0+2^2所以原式可以写成 

所以用一个数存储,到当前位是2的几次方,如果该位为1,说明需要乘上。

注意快速幂防止爆int须先转为long long在进行运算,不能运算完再强转

int qpow(int a,int n){int ans=1;while(n){if(n&1==1)ans=((ll)ans*a)%mod;//当前位为1n>>=1;//移位a=((ll)a*a)%mod;//当前位是2的几次方}return ans%mod;
}

快速幂求逆元

876. 快速幂求逆元 - AcWing题库

也就是b与p互质(gcd(b,p)==1且保证同余p结果相同的情况下,用a乘上x表示a/b。x就叫b的逆元 。

两边同乘b,除a

 由费马小定理,如果p为质数时

所以b与p互质且p为质数时逆元x=

又因为p为质数,b要与p互质只需要b不是p的整数倍即可。

所以p为质数时求b的逆元等效于求

使用快速幂

#include<bits/stdc++.h>
using namespace std;
int n;
int a,p;
#define ll long long
ll qpow(int a,int b){ll  ans=1;while(b){if(b&1)ans=(ll)ans*a%p;b>>=1;a=(ll)a*a%p;}return ans%p;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);
}
int main(){cin>>n;while(n--){cin>>a>>p;int res=qpow(a,p-2);if(a%p!=0){//(gcd(a,p)==1.p为质数,其他数若与他互质,只能不是p的整数倍cout<<res<<endl;}elsecout<<"impossible\n";}
}

简单数论入门和基础数学知识(未完)相关推荐

  1. 基础数学知识(未完待续)

    0x10 质数 质数基本定理 质数的定义:只被 1 1 1 和它本身整除的正整数叫做质数.非质数的正整数叫做合数.特别的, 1 1 1 既不是质数也不是合数. 质数的数量很少. 只有 2 2 2 是偶 ...

  2. 深度学习/机器学习入门基础数学知识整理(一):线性代数基础,矩阵,范数等

    前面大概有2年时间,利用业余时间断断续续写了一个机器学习方法系列,和深度学习方法系列,还有一个三十分钟理解系列(一些趣味知识):新的一年开始了,今年给自己定的学习目标--以补齐基础理论为重点,研究一些 ...

  3. 和与余数的和同余理解_5 同余 ——数论入门知识讲解系列

    数学竞赛 数论是纯粹数学的分支之一,主要研究整数的性质,按研究方法分为初等数论和高等数论.中学生(甚至小学生)课外数学兴趣小组的许多内容是属于初等数论的,各级别数学竞赛也会把初等数论作为重点内容进行考 ...

  4. c# 类的基本知识,未完,待续

    1.访问修饰符的使用,如果函数或者是成员变量被public修饰的话,那么可以在该class之外访问,如果是private的话是不能在这个类 之外来访问的,c#中默认的是使用private修饰符,但是作 ...

  5. Linux下简单创建ThinkPHP 6.0的网站 - 简单前后端 (未完待续)

    步骤 ssh user@ip-of-linux cd /var/www/ mkdir xiazai.rudon.cn cd xiazai.rudon.cn/ composer create-proje ...

  6. pythonb超分辨成像_Papers | 超分辨 + 深度学习(未完待续)

    1. SRCNN 1.1. Contribution end-to-end深度学习应用在超分辨领域的开山之作(非 end-to-end 见 Story.3 ). 指出了超分辨方向上传统方法( spar ...

  7. 学完oracle 再学mysql_一篇文章让Oracle程序猿学会MySql【未完待续】

    一篇文章让Oracle DB学会MySql[未完待续] 随笔前言: 本篇文章是针对已经能够熟练使用Oracle数据库的DB所写的快速学会MySql,为什么敢这么说,是因为本人认为Oracle在功能性方 ...

  8. 省钱版----查找 IoT 设备TTL线序__未完待续

    作者:仙果 原文来自:省钱版--查找 IoT 设备TTL线序 省钱版----查找 IoT 设备TTL线序__未完待续 缘由 在IoT固件调试分析的过程中,建议首先在IoT设备的板子上焊接调试线,这是能 ...

  9. 进阶之路(故事未完待续)

       加入爪哇第一天:9月11日    第一周:      呀,过中秋去了      所以,什么都没做-真是一个懒惰的银    第二周:      正式在周六的下午踏入了707,感觉好好      目 ...

  10. ECharts教程(未完)

    ECharts 特性 兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等) 底层依赖轻量级的矢量图形库 ZRender 丰富的可视化类型 常规的折线图.柱状图 ...

最新文章

  1. 了不起的Virtual DOM(一):起源
  2. 获取新浪网的链接信息
  3. Python学习---Django路由系统【all】
  4. 小鹤双拼记忆口诀_选择双拼之自然码
  5. Nsrp实现juniper防火墙的高可用性【HA】!
  6. php动态增加div,JavaScript动态创建div等元素实例
  7. 虚幻引擎3的代码讲解
  8. MapGIS数据中心是什么?
  9. 【心得感想】谈谈工作效率及沟通
  10. 万恶的BOM,万恶的微软
  11. 阿里云服务器运行django项目报错sqlite3版本低以及注意事项
  12. qnap raid5升级raid6_实践出真知!100TB的RAID5到底能否重建成功?
  13. [BJDCTF2020]Mark loves cat 1
  14. 电气潮流运算Matlab怎么编程,基于Matlab的电力系统潮流编程计算
  15. cncert/cc DDOS 清洗 流量清洗 IDC AFC AFD ICP
  16. 使用PowerShell下载必应图片
  17. 微信小程序数据绑定与模板语法
  18. 国产化软硬件系统解决方案
  19. Python操作EXCEL列转行
  20. 软件测试的相关工具——禅道(管理软件的生命周期)

热门文章

  1. 微电子学与计算机模板,微电子学专业个人简历模板
  2. html如何加载ae做好的,AE转JS动画,lottie.js和bodymovin的简易使用心得
  3. 如何在酷狗上下载付费歌曲
  4. SQL 插入时直接插入当前时间
  5. python保存文件后缀_python文件的后缀名是什么
  6. 利用C++求坐标系中两点间距离
  7. android svg 编辑器,Android svg 格式使用小结
  8. SM3算法的C++实现(代码)
  9. android 存储盘 dcim,Android上的DCIM目录路径 – 返回值
  10. python能刷网课吗_利用Python脚本实现自动刷网课