首页 > 代码库 > 复习基础素数
复习基础素数
#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; }
复习基础素数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。