【数学】NOIP数论内容整理
NOIP数论内容整理
注:特别感谢sdsy的zxy神仙以及lcez的tsr筮安帮助审稿
一、整除:
对于,若,,则说整除,记做
二、带余除法:
存在且仅存在唯一的,,其中。记做。
三、公约数
设,若,,则说是的公约数。公倍数同理。
四、与
记的最大公约数为,最小公倍数为
五、最大公约数与最小公倍数乘积性质定理
性质:
六:最大公约数的求取:(以下不妨设)
更相减损术:
欧几里得算法:
其中,更相减损术的复杂度是,欧几里得算法的复杂度是。其中
七:更相减损术的优化
引理:,有
当是两个偶数时,显然有一因数。于是
当一奇一偶的时候,不妨设是偶数。显然不含因子。于是有
当同为奇数时,直接应用更相减损术。。
考虑两个奇数相减答案显然是偶数。于是一次更相减损术显然对应一个数除以2的操作。即更相减损的次数与除以二的操作次数同阶。考虑一个数最多被除次。于是该算法的复杂度为。
该算法常用在对两个高精度数求,因为两个高精度数做除法的复杂度难以承受,从而应用该算法。
八、例题:
给定一个序列,要求支持区间加法。多次查询区间内所有数字的。
Solution:
因为区间加法无法维护,所以显然不能暴力线段树。考虑对原序列做差分。由更相减损定理,显然成立。于是差分后区间加法改为单点修改操作。于是一次操作的复杂度为。总时间复杂度为,可以通过本题。
九、扩展欧几里得算法
裴蜀定理:关于的方程有解当且仅当。
求关于的方程的一组整数解。
不妨设。否则左侧乘一常数,不失一般性
根据欧几里得算法,有
于是有
于是有
根据对应系数相等,显然有。考虑他的一组特解:当时,显然成立。
求上述方程的所有解
假设求出的该方程的一组特解,则该方程的所有解为。
十、素数:
有且仅有和本身两个因子的数是素数
十一、埃拉托色尼筛法:
对每个数只筛掉它的倍数。
int pcnt;
int prime[maxn];
bool is_not_prime[maxn];
void Get_Prime(int x) {
is_not_prime[1]=true;
for(int i=1;i<=x;++i) if(!is_not_prime[i]) {
prime[++pcnt]=i;
for(int j=i*i;j<=x;j+=i;) is_not_prime[j]=true;
}
}
十二:欧拉筛法
对每个数只被他的最小素因子筛掉
int pcnt;
int prime[maxn];
bool is_not_prime[maxn];
void Get_Prime(int x) {
is_not_prime[1]=true;
for(int i=2;i<=x;++i) {
if(!is_not_prime[i]) prime[++pcnt];
for(int j=1;j<=pcnt;++j) {
if(i*prime[j] > x) break;
is_not_prime[i*prime[j]]=true;
if(!(i%prime[j])) break;
}
}
}
十三:在时间内筛除以内所有数的素因子
对于每个数记录自己的最小素因子。对于第每个数,迭代将每个数除以自己的最小素因子。
int pcnt;
int prime[maxn],pre[maxn];
bool is_not_prime[maxn];
void Get_Prime(int x) {
is_not_prime[1]=true;
for(int i=2;i<=x;++i) {
if(!is_not_prime[i]) prime[++pcnt],pre[i]=pcnt;
for(rg int j=1;j<=pcnt;++j) {
if(i*prime[j] > x) break;
is_not_prime[i*prime[j]]=true;
pre[i*prime[j]]=j;
if(!(i%prime[j])) break;
}
}
}
void ans(int x) {
for(int i=1;i<=x;++i) {
printf("%d:",i);
int di=i;
while(di != 1) printf("%d",prime[pre[di]]),di/=prime[pre[di]];
putchar('\n');
}
}
十四、唯一分解定理:
,存在且仅存在一个形如的等式。其中满足为质数,
则对于的,其唯一分解式对应位置的指数取即为对应的的唯一分解式
十五、欧拉phi函数:
定义:为中与互质的数的个数
其中为的唯一分解式对应底数。
证明:不妨设只有两个因数。否则做数学归纳
则与互质的数的个数为减去的倍数和的倍数。根据容斥原理,应加回的倍数。即
对于有更多因数的情况,可以依据唯一分解定理做数学归纳。证毕。
求单个数字的函数:
暴力枚举质因数。复杂度
埃拉托色尼筛法:
对每个质数,修改他的倍数的函数值
int pcnt;
int prime[maxn],phi[maxn];
bool is_not_prime[maxn];
void euler(int x) {
for(int i=1;i<=x;++i) phi[i]=i;
for(int i=2;i<=x;++i) if(!is_not_prime[i]) {
prime[++pcnt]=i;phi[i]=i-1;
for(rg int j=i*i;j<=x;j+=i) {
is_not_prime[j]=true;
phi[j]=phi[j]/i*(i-1);
}
}
}
欧拉筛:
对每个数,只被他的最小质因子筛掉。
考虑通过一个质因子求出他的欧拉函数值。
引理:为质数,显然。
定理一:,若与不互质,则
证明:
不妨设 有且仅有 两个质因子,否则对做数学归纳,不失一般性
则
于是由容斥原理有
上式除以下式,得
移项整理后,原式得证。
证毕。
定理二:,若与互质,则
证明:
易证函数为积性函数。因为与互质,于是
又因为是一个质数,于是根据引理,。
原式得证。
证毕。
于是对于每个数,若他是质数,则应用引理,否则在筛时,若最小质因子与他互质,则应用定理二,否则应用定理一。
int pcnt;
int prime[maxn],phi[maxn];
bool is_not_prime[maxn];
void euler(int x) {
phi[1]=1;
is_not_prime[1]=true;
for(int i=1;i<=x;++i) {
if(!is_not_prime[i]) prime[++pcnt]=i,phi[i]=i-1;
for(int j=1;j<=pcnt;++j) {
if(i*prime[j] > x) break;
is_not_prime[i * prime[j]]=true;
if(!(i%prime[j])) {phi[i*prime[j]]=phi[i]*prime[j];break;}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
十六、模方程:
定义:,若 则称作在模域下同余。记做。
同余式两边支持同时加、减、乘同一个数字,但不支持除法。
十七、模逆元:
,若则称是在模域下的逆元。在模域下,任何一个整数除以完全等价于乘。
一般而言,为质数是存在逆元的充分条件
十八、逆元的求法
单个数求逆元
解方程,发现等价于。直接使用求得答案即可。
线性筛逆元:
记的逆元为,数组表示为
则有线性递推式:
证明:
对于所有的,写出他的带余除法表达式:
在域下有:
等式两侧同乘
化简,整理得到:
因为,原式得证。
int inv[maxn];
void Get_inv(int x,int p) {
inv[1]=1;
for(int i=2;i<=x;++i) inv[i]=(p-p/i)*inv[p%i]%p;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)