我们知道在求素数时,普通的暴力通常无法满足许多OJ网站的时间复杂度要求,那么自然需要优化,我们求素数时,不妨把不是素数的先标记,剩下的自然就都是素数(直接暴力这里就不写了)。
埃塞:
#include<bits/stdc++.h> using namespace std; #define ll long long int prime[20000]; int len; int main() { int n; cin>>n; int book[20000]; memset(book,0,sizeof(book)); for(register int i=2;i<=n;i++) { if(!book[i]) { prime[len++] = i; for(register int j=2*i;j<=n;j+=i) {//每次把这个数的倍数标记 book[j] = 1; } } } /*for(register int i=0;i<len;i++) { cout<<prime[i]<<endl; }*/ }埃筛其实还是有一些重复:许多数被重复标记,比如:10既被2标记过,又被5标记过
接下来是线性筛:线性筛的优化主要在于每个数只被筛过一次
#include<bits/stdc++.h> using namespace std; #define ll long long int prime[20000]; int len; int main() { int n; cin>>n; int book[20000]; memset(book,0,sizeof(book)); for(register int i=2;i<=n;i++) { if(!book[i]) { prime[len++] = i; } for(register int j=0;j<len;j++) { if(i*prime[j]>n) break; book[i*prime[j]] = 1; if(i%prime[j]==0)//使每个合数只被它的最小质因数标记 break; } } /*for(register int i=0;i<len;i++) { cout<<prime[i]<<endl; }*/ }
