质数
试除法判定质数(时间O(sqrt(n)))
模板:
bool check(int x)
{
if(x<=1) return false;
for(int i=2;i<=x/i;i++)
{
if(x%i==0) return false;
}
return true;
}
分解质因数
模板:
void check(int x)
{
for(int i=2;i<=x/i;i++)
{
if(x%i==0)
{
int s=0;
while(x%i==0)
{
x/=i, s++;
}
cout << i << " " << s << endl;
}
}
if(x>1) cout << x << " " << 1 << endl;
return ;
}
筛质数
1.最普通的筛法 O(nlogn)
void get_primes(){
for(int i=2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i;//储存质数
for(int j=i;j<=n;j+=i)
st[j]=true;
}
}
2.诶氏筛法 O(nloglogn)
埃氏筛法之所以能用质数将所有的合数删掉,就是因为如果没有被标记那么证明这个数不是他前面的数的倍数,那么他一定是质数。
void get_primes(){
for(int i=2;i<=n;i++){
if(!st[i]){
primes[cnt++]=i;
for(int j=i;j<=n;j+=i)
st[j]=true;
}
}
}
3.线性筛法 O(n)
void get_primes(int x)
{
for(int i=2;i<=x;i++)
{
if(!st[i]) cnt[sum++]=i;
for(int j=1;cnt[j]<=x/i;j++)
{
st[cnt[j]*i]=true;
if(i%cnt[j]==0) break;
}
}
}
线性筛选只需将所有的合数都标记,而内层循环跳出的条件是(质数是等于本身跳出吗,合数是找到最小质因数跳出);
假设有一个合数x,i=x/pj ; 那么x会在外层循环等于i时被标记,内层循环跳出的条件 是 i 找到最小质因数,x是 i 的倍数,那么在i找到最小质因数之前 x 也一定会找到质因数。
线性筛选法的时间复杂度是 O(n),因为每个质数都只被最小质因数标记过一次,没有重复标记。