用 Eratosthenes筛法构造1-n的素数表.
算法的思想: 对于不超过n的每个非负整数p, 删除2p,3p,4p....., 当处理完所有数之后, 还没被删除的就是素数. 用vis[i]表示已经被删除的数.
简单的算法可以表示成:
for ( int i = 2; i <= n; i++) { for ( int j = i*2; j <= n; j+=i ) vis[j] = 1; }
因为小于n的素数的个数小于等于lgn ( 相关证明可以在初等数论第一章中找到 ), 可以缩短外层循环.
int m = sqrt(n + 0.5); for ( int i = 2; i <= m; i++) { if (!vis[i]) for ( int j = i*2; j <= n; j+=i ) vis[j] = 1; } }
这种思路也可以用来解答其它相似问题, 比如无平方因子数(整数p无平方因子当且仅当不存在k>1,使得p是k^2的倍数).
ps: 素数定理, 不超过x的素数的个数跟 x/lnx比较接近
psps..跟素数相关的性质还有好多, 等有精力去写数论笔记...