C++ 数论相关题目(试除法判质数、分解质因数、筛质数)

1、试除法判定质数

只要记得需要优化一下,不用枚举到n,利用质数性质枚举到n/i就行
时间复杂度 根号n

#include 
#include 

using namespace std;

int n;

bool judge(int a)
{
    if(a < 2)
        return false;
    for(int i = 2; i <= a / i; i ++ )
        if(a % i == 0)
            return false;
    
    return true;
}


int main ()
{
    cin>>n;
    while(n -- )
    {
        int a;
        cin>>a;
        if(judge(a))
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
    
    return 0;
    
}

2、分解质因数

正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以用指数表示。根据算术基本定理,任何正整数皆有独一无二的质因子分解式
主要是函数内的优化,首先还是n最多只有一个大于根号n的质因数,因此还是枚举到n/i,枚举完之后需要再判断一下是否大于1,如果大于1,则说明有大于根号n的质因数,直接输出就行。
时间复杂度根号n(介于logn 和根号n之间)

#include 

using namespace std;

int n;

void solve(int a)
{
     for(int i = 2; i <= a / i; i ++ )
     {
         if(a % i == 0)
         {
             int s = 0;
             while(a % i == 0)
             {
                 a /= i;
                 s ++;
             }
             cout<<i<<" "<<s<<endl;
         }
     }
     if(a > 1) 
        cout<<a<<" "<<1<<endl;
     cout<<endl;
}

int main ()
{
    cin>>n;
    while(n -- )
    {
        int a;
        cin>>a;
        solve(a);
    }
    
    return 0;
}

3、筛质数

主要就是遍历一遍把前面一个小质数的倍数给ban掉。
时间复杂度nlnn ,也就是nlogn

#include 

using namespace std;

const int N = 1000010;
int n;
int cnt;
bool st[N];

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

int main ()
{
    cin>>n;
    
    get_primes(n);
    
    cout<<cnt<<endl;
    
    return 0;
}

优化:筛的时候把ban掉的过程放进判断里,也就是只需要把质数的倍数ban掉。
时间复杂度:nloglogn,基本和O(n)一个级别。

#include 

using namespace std;

const int N = 1000010;
int n;
int cnt;
bool st[N];

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

int main ()
{
    cin>>n;
    
    get_primes(n);
    
    cout<<cnt<<endl;
    
    return 0;
}

在这里插入图片描述
可以看到在10e6下快了几倍。
除此之外还有线性筛法,在7次方或者更大数量级大概会再快一倍,在这里就不赘述了,感兴趣的可以自行百度。

你可能感兴趣的:(力扣,算法笔记,数论,c++,数论)