算法竞赛中围绕数论三个重要问题
1.素数运算实验范例
1).计算[2,n]区间中所有素数
2) 大整数素数测试
1.1 使用筛法生成[2,n]区间中所有素数
a. 最简单之埃拉托斯特尼筛法
思想:辅助数组做筛子,递增搜索筛子中最小数,把被搜索数的倍数从筛中去掉,最后留下的数字是素数
实现代码:
#include <iostream>
#define MAXN 50005
using namespace std;
bool u[MAXN]; //辅助数组做筛子
int su[MAXN]; //素数集合
void SieveOfEratosthenes(int n)
{
int i,j,num=0;
for(i=2;i<=n;i++)
{
u[i]=true;
}
for(i=2;i<=n;i++)
{
su[i]=true;
}
for(i=2;i<=n;i++)
{
if(u[i])
{
for(j=2;j*i<=n;j++)
{
u[j*i]=false;
}
}
}
for(i=2;i<=n;i++)
{
if(u[i])
{
su[num++]=i;
}
}
}
// Test
int main()
{
SieveOfEratosthenes(100);
for(int i=0;i<=100;i++)
{
if(su[i]!=0&&su[i]!=1)
cout<<su[i]<<endl;
}
return 0;
}
时间复杂度:O(n*long(long n))
b.加一点优化就是欧拉筛法
思想:埃氏筛法中,每一个合数重复计算,欧拉筛法就是优化到每一个合数仅算一次筛掉,优化算法
实现代码:
#define MAXN 50005
bool u[MAXN]; //辅助数组做筛子
int su[MAXN]; //素数集合
void SieveofEuler(int n)
{
int i,j,num=0;
memset(u,true,sizeof(u));
for(i=2;i<=n;i++)
{
if(u[i])
{
su[num++]=i;
}
for(j=0;j<=num;j++)
{
if(i*su[j]>n)
{
break;
}
u[i*su[j]]=false;
if(i%su[j]==0)
{
break;
}
}
}
}
//Test
int main()
{
SieveofEuler(100);
for(int i=0;i<=100;i++)
{
if(su[i]!=0)
cout<<su[i]<<endl;
}
return 0;
}
时间复杂度:O(n)