事情是这样的:今天上OI课程,snowycat讲解STL 的算法,突然就讲到了欧拉筛,当时还有一会儿就下课了,所以我就开了会儿小差(什么逻辑?)就开始写素数的式子,感觉突然发现了一种很新的算法,认为值得写一下,毕竟如果是已经出现的,就当头脑风暴,如果没出现,率先发现也很nice对吧!
我们先来看100以内的素数:
2、3、5、7、11、13、17、19、23、29、31、37、41、43、47、53、59、61、67、71、73、79、83、89、97
除了2和3以外,我们不难发现,其实每一个素数都可以表示为含有2和3的关系式:
2 = breakI
3 = breakII
7 = 2*3+1; first
11 = 2*3*2-1; second
13 = 2*3*2+1; first
17 = 2*3*3-1; second
19 = 2*3*3+1; first
23 = 2*3*4-1; second
29 = 2*3*5-1; second
31 = 2*3*4+1; first
37 = 2*3*6+1; first
41 = 2*3*7-1; second
43 = 2*3*7+1; first
47 = 2*3*8-1; second
53 = 2*3*9-1; second
59 = 2*3*10-1; second
61 = 2*3*10+1; first
67 = 2*3*11+1; first
71 = 2*3*12-1; second
73 = 2*3*12+1; first
79 = 2*3*13+1; first
83 = 2*3*14-1; second
89 = 2*3*15-1; second
97 = 2*3*16+1; first
如果拓展到n
那就是
I:
(n + 1) % 6 == 0;
II:
(n - 1) % 6 == 0;
我所定义的first和second指的是后面是加法还是减法
如果说我们定义上flag,那就可以发现2和3其实是边界,而其实素数应该满足上面I和II的表达式
那如果拓展到一般情况该怎么办呢?
我们不难发现,对于一列公差为1的数,我们可以任意的对其分割周期
所以说我们的边界为2和3,那也就是下一次的周期应该是2*3=6
一般的
就会有6n,6n+1,6n+2,6n+3,6n+4,6n+5,6n+6(6n)
我们来看
6n,6n+2,6n+4,6n+6一定为偶数,所以不是素数
同样6n+3也一定是3的倍数
所以只剩下了6n+1和6n+5
想一个例外
6n+5可能是5的倍数怎么办?
没有事情的,在循环里去除就行了
或者说,在我们便利6n+1和6n+5时只需要额外的操作一下就可以了,例如2*3*4+1=25,但是25并不是素数
相似的,还有2*3*6-1=35,2*3*8+1=49
那么这些数满足什么式子呢?
不难发现,这几个数都是(6m±1)*(6n±1);的形式
所以在循环里只需要排除掉就可以了
好,不多说了(copyright@大连市第二十四中学地理姜亮老师)上代码:
#include<bits/stdc++.h>
using namespace std;
bool check(long long n)
{
if (n == 1)
return false;
else
if (n == 2 || n == 3)
return true;
else
if (n % 6 != 1 && n % 6 != 5)
return false;
for(int i = 5;i <= sqrt(n);i += 6)
{
if (n % i == 0 || n % (i + 2) == 0)
return false;
}
return true;
}
int main()
{
long long min,max;
long long sum = 0;
cin >> min >> max;
for(int i = min;i <= max;i ++)
{
if(check(i) == true)
{
cout << i << " ";
sum ++;
}
}
cout << sum;
return 0;
}
时间复杂度
关于时间复杂度,(有两种观点)
基本同意了观点
I:
O(n*sqrt(n))
II:
O(n+sqrt(n))
应该是O(n^3/2)
以后测出具体的数值再更
在100000000时比欧拉筛慢1-2秒,但是结果符合,所以应该没有什么问题。
感谢OI的朋友们帮我测复杂度并指出了我的错误,的确是比欧拉筛要慢很多(20231216更新)
写在后面
请原谅我的狂妄
但是如果真的是在下第一个发现的
我想将其命名为:廿四筛
写在后面II
感谢:AClove,viki617,Qwehhh123,snowycat1234帮助我正确的测算时间复杂度并优化
作者分享了在OI课程中通过观察素数规律,发现的一种新算法,利用2和3的关系简化素数判断,提出廿四筛,虽然时间复杂度较欧拉筛稍慢,但具有启发性。
1万+

被折叠的 条评论
为什么被折叠?



