【基础向】mx 不会数论 /kel

注:本文按 MX 主观顺序排列

基础

()

快速幂

int qp(int a,int b){
	long long ans=1,base=a;
	while(b>0){
		if(b&1)(ans*=base)%=p;
		(base*=base)%=p;
		b>>=1;
	}
	return ans%p;
}

质数

单质数判断

试除法

\(2\) ~ \(\sqrt{n}\) 之间有没有可以被 \(n\) 整除的,暴力枚举。

P1075 [NOIP2012 普及组] 质因数分解

tips:从小到大枚举,不然会 TLE。

多质数判断

埃氏筛

for(int i=2;i<=n;i++){
	if(pri[i])continue;
	res[++cnt]=i;
	for(int j=2;i*j<=n;j++)pri[j*i]=1;
}

时间复杂度为 \(O(n \log^2n)\)

优化: \(j=2\) 改成 \(j=i\),因为那些小于 \(i\) 的倍数枚举,都一定在 \(i\) 之前被遍历过。

欧拉筛

for(int i=2;i<=n;i++){
	if(!pr[i])prs[++cnt]=i;
	for(int j=1;j<=cnt&&i*prs[j]<=n;j++){
		pr[i*prs[j]]=1;
		if(i% prs[j]==0)break;
	}
}

原理:保证了每一个合数只被其最小的质因子遍历,所以时间复杂度为 \(O(n)\)

证明(by 乐宝/qq):

因为当我们发现了 \(i=k\times pri[j]\) 时,我们在用 \(i\)\(pri[j+1]\) 遍历区间时会重复。
因为 \(i=k\times pri[j]\),所以 \(i\times pri[j+1]=k\times pri[j]\times pri[j+1]\) 因为 \(pri\) 数组中的素数是单调递增的,所以这样会使得在后面遍历的时候 \(pri[j+1]\times i\) 被重复遍历。

线性筛

for(int i=2;i<=n;i++){
	if(!v[i]){
		pri[++cnt]=i;
		v[i]=i;
	}
	for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
		if(pri[j]>v[i])break;
		v[i*pri[j]]=pri[j];
	}
}

本质:从大到小累计质因子。

每个合数 \(i\times p\) 只会被它的最小质因子 \(p\) 筛一次,所以时间复杂度为 \(O(n)\)

算术基本定理

任何一个大于 \(1\) 的正整数都能唯一的分解为有限个质数的乘积,即 \(N=p_1^{c_1}p_2^{c_2}...p_m^{c_m}\)

其中。\(c_i\) 都是正整数,\(p_i\) 都是质数。

试除法

注意最后要有 if(n>1)p[++cnt]=n,c[cnt]=1;

posted @ 2023-06-20 14:33  MX_muxi  阅读(26)  评论(0)    收藏  举报
Title