一:关于质数

大于1

只包含1和其本身两个因数

二:

1:质数的判定:试除法

2:分解质因数:试除法

直接算的话,复杂度O(n)

优化:(1)性质:n中最多只包含一个大于sqrt(n)的质因子,咋直接枚举到sqrt(n)即可。最后加个特判,如果n>1,算一个因子。

适用于n<=2e9

#include <bits/stdc++.h>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 1e3+10;
//vector<int>g[maxn];
void _get(ll n)
{
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
int cnt=0;
while(n%i==0)
{
n=n/i;
cnt++;
}
cout<<i<<" "<<cnt<<endl;
}
}
if(n>1)
cout<<n<<" "<<1<<endl;
cout<<endl;
}
int main(){
int t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
_get(n);

}
}

3:筛素数

1:最最普通的筛,对于一个素数i,每次由它往后标记掉j+=i

复杂度:n*Iogn

void _get(ll n)
{
memset(st,false,sizeof(st));

for(int i=2;i<=n;i++)
{
if(!st[i])
{
pr[cnt++]=i;
}
for(int j=i+i;j<=n;j+=i)
{
st[j]=true;
}
}
}

2:优化上述

只筛质数的倍数,大概可以快三倍左右

for(int i=2;i<=n;i++)
{
if(!st[i])
{
pr[cnt++]=i;
for(int j=i+i;j<=n;j+=i)
{
st[j]=true;
}
}
}

3:埃氏筛法(O(nloglogn))

整数的唯一分解定理:任何一个大于1的自然数 N,如果N不为质数,都可以唯一分解成有限个质数的乘积

for(int i=2;i<=n;i++)
{
if(!st[i])
{
pr[cnt++]=i;
for(int j=i+i;j<=n;j+=i)
{
st[j]=true;
}
}
}

4:线性筛(欧拉筛法)(O(n))

是在埃氏筛法的基础上,让每一个合数,只被它的最小质因子筛选一次,避免重复筛。

关于 i % pr[j]==0 break;

如果i%pr[j]==0,那么i==pr[j]*k

如果接着标记,那么就有st[pr[j+1]*i]=true;

而i*pr[j+1]==pr[j+1]*k*pr[j]==x,即以后的循环中,如果i==pr[j]*k,x还会被筛一次。

 

void init()
{
memset(st,false,sizeof(st));
for(int i=2;i<maxn;i++)
{
if(!st[i])
pr[cnt++]=i;
for(int j=0;pr[j]*i<maxn&&j<cnt;j++)
{
st[pr[j]*i]=true;
if(i%pr[j]==0) //欧拉筛的关键,防止重复筛,保证合数只被其最小的素因子筛一次
{
break;
}
}
}
}