首页 > 代码库 > 复习基础素数

复习基础素数

#include<iostream>
#include<cstdio>
#include<cmath>
#define maxn 100009
using namespace std;
typedef long long ll;
int check_prime(int x)// 普通的素数判定 这里的最简单的优化就是sqrt(x)范围的缩小 假设有一个数b n能整除b 那么就有n/b存在 那什么时候因数最大呢 当n/b=b的时候 也就是sqrt(n)的时候
{
    if(x==1) return 0;
    for(int i=2;i<=sqrt(x);i++)
    {
        if(x%i==0) return 0;
    }
    return 1;
}
int is_prime[maxn],prim[maxn];
int sieve_prime(int n)// 素数筛法 整数倍的筛去
{
    int ret=0;
    fill(is_prime+2,is_prime+n+1,1);//
    for(int i=2;i<=n;i++)
    {
        if(is_prime[i])
        {
            prim[ret++]=i;
            for(int j=i*2;j<=n;j+=i) is_prime[i]=0;
        }
    }
    return ret;
}
ll Is_prime[maxn],Is_primesmall[maxn];

// 对[a,b)这个区间求素数的个数,当a,b的范围都很大的时候,就需要一些改良了 我们知道小于b的合数的最大因子在sqrt[b]之内 那我们做一个2~sqrt(b)的表 在筛选这个表的同时 把[a,b)区间的合数也一并筛掉 那么[a,b)剩下的就是素数了 // [2,b]这个区间可以sieve [2,b*b]内的合数
void segement_sieve(ll a,ll b)// 大区间的素数筛法 { for(int i=0;(ll)i*i<b;i++) Is_primesmall[i]=1; for(int i=0;i<b-a;i++) Is_prime[maxn]=1; for(int i=2;(ll)i*i<b;i++) { if(Is_primesmall[i]) { for(int j=i*2;(ll)j*j<b;j++) Is_primesmall[j]=0;// 由于b是ll类型 所以这里用 (ll)j*j<b 来代替j<sqrt(b) for(ll j=max(2LL,(a+i-1)/i)*i;j<=b;j+=i) Is_prime[j-a]=0;// 由于数据太大 这里用j-a哈希一下 // 慢慢的细节, 数字后面加LL是为了保证类型一致 max(2LL,(a+i-1)/i)用来求i最接近a的倍数,最小是两倍 牛逼 } } } int main() { int n; cin>>n; while(n--) { int x; cin>>x; if(check_prime(x)) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }

复习基础素数