1.\(对于一个足够大的整数N,不超过N的质数大约有N/lnN个,即每lnN个数中大约有1个质数.\)
2.\(约数总是成对出现的,如果M|N,则\frac{N}{M}|N.\)
- 试除法判定质数
bool is_prime(int n)
{
for(int i=2;i<=n/i;i++)
if(n%i==0)return flase;
return true;
}
- 筛质数:\(给定整数N,求出1\sim{N}之间所有的质数\)
1.埃氏筛法
原理:
\(任意整数X的倍数都不是质数.\)
证明:
\(对于2<=P<=N,如果P最后没有被筛掉,则P不是{2}\sim{P-1}中任何一个数的倍数,\)
\(同理2\sim{P-1}没有一个数是P的约数,根据质数定义,P是质数\)
\(复杂度O(loglog N)\)
int cnt,primes[N],st[N];
void f(int n)
{
for(int i=2;i<=n;i++)
{
if(st[i])//如果不是质数
continue;
primes[cnt++]=i;
for(int j=i+i;j<=n;j+=i)//只筛质数的倍数
st[j]=1;
/*
更快一些的写法
for(int j=i;j<=n/i;j++)等价于for(int j=i;j*i<=n;j++)在整数N范围内对质数的倍数进行标记
st[j*i]=1;*/
}
}
2.线性筛法
核心:
\(每个合数只会被它的最小质因子筛掉,保证了时间复杂度是O(N)\)
\(例如6在\underline{埃氏筛}中会被2,3筛两次,\underline{线性筛}中希望6(合数)只被2筛一次\)
const int N=1e6+10;
int cnt,n,p[N],st[N];
cin>>n;
for(int i=2;i<=n;i++)
{
if(!st[i])p[cnt++]=i;
for(int j=0;j
- 质因数分解:
1.算术基本定理
\(任何一个大于1的正整数都能唯一分解为有限个质数的乘积:\)
\( N=p_1^{c_1}p_2^{c_2}...p_m^{c_m} \\其中c_i都是正整数,p_i都是质数,且满足p_1
2.重要定理
\( 对于整数N,最多只有一个大于\sqrt{N}的质因子 \\ 反证法:如果N有多个大于\sqrt{N},那么他们的乘积>N,矛盾 \)
void f(int k)
{
for(int i=2;i<=k/i;i++)
{
int cnt=0;
if(k%i==0)//i一定是质数,因为有下面的while循环,对于K来说
{ //K的合数因子一定在扫描到这个合数之前就被质数从K中除掉了
//所以能整除K的一定不是合数。
cout<1)
cout<