质数与整除
1.gcd与lcm
\({gcd(a,b)}\cdot{lcm(a,b)}=ab\)
\(d\)是\(a,b\)的公约数\(\Longleftrightarrow d|\gcd(a,b)\)
\(a,b\)正整数且\(a>b\),有:
\(gcd(b,a)=gcd(b,a\bmod b)\)
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
复杂度\(O(\log{\max(a,b)})\)
2.质数
2.1质数个数
\(\pi(n)\)为不大于\(n\)的质数个数,则有:
\(\pi(n)=O(\frac{n}{\log{n}})\)
2.2唯一分解定理
\(n=\prod_{i=1}^m {p_i}^{k_i}\)
其中\(p_i\)互不相同为质数,\(k_i\)为正整数,有
\(m=O(\log{\log{n}})\)
void factor(int n){//p为质数数组
for(int i=1;i<=p[0];i++){
if(p[i]*p[i]>n) break;
while(!(n%p[i])){
f[++f[0]]=p[i];
n/=p[i];
}
}
if(n>1) f[++f[0]]=n;
}
复杂度为\(O(\frac{\sqrt{n}}{\log{n}})\)
2.3筛法
线性筛:从2到n枚举i,在从小到达枚举不大于i的最小质因数的质数\({p_0}\),标记\(i{p_0}\)。枚举到的\(p_0\)总是\(i{p_0}\)的最小质因数,而更大的\(p_0\)均不是\(i{p_0}\)的最小质因数。
每个合数都只在其最小质因子被枚举时标记,故复杂度\(O(n)\)
void getprime(){
for(int i=2;i<=n;i++){
if(!vis[i]) p[++p[0]]=i;
for(int j=1;i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(!(i%p[j])) break;//第一次枚举到最小质因子就跳出
}
}
}