素数常用两种方法
比赛时需要找素数给我顿住了,赶紧做一篇博客记录一下找素数的两种常用方法
1.暴力枚举 (偷懒数小的时候用)
时间复杂度O(n*sqrt(n))
一个个枚举根据素数定义判断即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N = 1e5+5;
int prime[N];
int main()
{
int k=0,flag=0;
for(int i=2;i<N/2;i++)
{
for(int j=2;j*j<=i;j++)
{
if(i%j==0)
{
flag=1;
break;
}
}
if(!flag)
prime[k++]=i;
}
return 0;
}
最大不超过1e5-1e6之间
2.线性筛(优化)
时间复杂度降到O(n) ,非常好用
#include<bits/stdc++.h>
#define ri int
using namespace std;
typedef int lll;
typedef long long ll;
vector<ll> vis(N);
vector<ll> prime(N);
ll k=0;
void isprime()
{
for(ri i=2;i<N;i++)
{
if(!vis[i]) prime[++k]=i;
for(ri j=1;j<=k&&(i*prime[j]<N);j++)
{
vis[i*prime[j]]=1;
if(!i%prime[j]) break;
}
}
}
参考博客 素数筛
整体是通过 素数的倍数 不是素数这一原理,再如果本身i是素数的倍数,那么可以不进行筛选(if(!i%prime[j]) break;)
达到优化结果