您的位置:首页 > 其它

数论基础_素数相关

2011-08-09 10:38 190 查看
1.素数判定

普通的算法即O(sqrt(N))的试除法,高级些的Miller_Rabin素数测试.

但NOIP似乎用不着Miller_Rabin,试除法又非常简单,就不在这里写了.

2.求素数

筛法是比较常见的方法.埃拉托色尼斯筛法可以对付一般的题目了.

但我想写写线性筛法.

先给code:

const MAX=1000000;
var   Prime:array[0..MAX] of longint;
v:array[0..MAX] of boolean;

procedure GetPrime;
var   i,j,tmp,size:longint;
begin
size:=0;
fillchar(v,sizeof(v),0);
for i:=2 to MAX do
begin
if not v[i] then
begin
inc(size);
prime[size]:=i;
end;
j:=1;
while (j<=size)and(prime[j]*i<MAX) do
begin
v[i*prime[j]]:=true;
if i mod prime[j]=0 then break;
inc(j);
end;
end;
end;

begin
GetPrime;
end.


算法的核心在于while循环内的语句.

首先,prime[j]一定是i的最小质因子,因此也是i*prime[j]的最小质因子.

然后又有了这句话:if i mod prime[j]=0 then break;

于是算法就保证了每个合数只被它的最小质因子筛去,且仅筛去一次.

那么会不会漏掉某些合数没有筛去呢?不会.

因为i*prime[j'](j'>j)一定被prime[j]乘上以后的某个更大的i'筛去。
∵i'*prime[j]=i*prime[j']
∴i'=i/prime[j]*prime[j']>i

所以是O(N)效率的.

线性筛法的作用不只是求素数,以后还会写到其他的应用.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: