标题一
定义
质数(prime number)又称素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
一、素数的判定
试除法:
定理:若一个正整数是合数,则存在一个能整除N的数K,2≤K≤sqrt(n)
证明:反证法
Eratosthens筛选法
基本思想:质数的倍数一定不是质数
时间复杂度: O(n㏒㏒n)
欧拉线性筛
由于每个大于等于2的合数必定存在一个最小的质因数,所以只要筛去每个质数的倍数就相当于筛去了所有合数。
但欧拉筛相比埃氏筛最大的优化就在于欧拉筛保证每个合数只被筛了一次,且是被其最小的质因数筛去的,所以欧拉筛的时间复杂度可以达到O(N)。
代码
#include
#include
#define FORa(i,s,e) for(int i=s;i<=e;i++)
#define FORs(i,s,e) for(int i=s;i>=e;i--)
#define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),pa==pb)?EOF:*pa++
#define File(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout);
using namespace std;
static char buf[100000],*pa=buf,*pb=buf;
inline int read();
const int N=1000;
int n,cnt,v[N+1],prime[N+1];
int main()
{
scanf("%d",&n);
/*优化空间的欧拉质数筛 FORa(i,2,n)
{
if(!bz[i]) prime[++cnt]=i;
FORa(j,1,cnt)
{
if(i*prime[j]>n) break;
bz[i*prime[j]]=true;
if(i%prime[j]==0)
break;
}
}*/
FORa(i,2,n)
{
if(!v[i]) v[i]=i,prime[++cnt]=i;
FORa(j,1,cnt)
{
if(prime[j]>v[i]||prime[j]*i>n) break;
/*因为整个程序会经过整个队列,所以可以保证都会被筛
prime[j]>v[i]是为了prime[j]*i不被再次被筛
如果 prime[j]>v[i]就说明之后的v[prime[j]*i]在后续就会被筛 */
v[prime[j]*i]=prime[j];
}