素数常用两种方法

比赛时需要找素数给我顿住了,赶紧做一篇博客记录一下找素数的两种常用方法

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;)

达到优化结果

posted @ 2021-07-20 14:37  gonghw403  阅读(101)  评论(0编辑  收藏  举报