Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说欧拉筛(线性筛)& 欧拉函数,希望能够帮助你!!!。
今天又复习了一下欧拉筛法,在这做个笔记。
一般情况下,有一种筛法叫埃什么什么的。是 O(nloglogn) ,非常接近于 O(n) ,但也会有坑爹的出题人来个10000000故意卡你。
这可能原理有点妙啊。
这样可以发现,每一个数只会被它最小的质因子筛去,所以保证了算法为 O(n) 的。
我们见一下代码:
void find_prime(int n)
{
memset(isprime,0,sizeof(isprime));
sp = 0;
for(int i = 2;i <= n;i++)
{
if(!isprime[i])
{
prime[++sp] = i;
isprime[i] = i;
}
for(int j = 1;j <= sp && i * prime[j] <= n;j++) {
isprime[i*prime[j]] = prime[j];
if(prime[j] >= isprime[i]) break;//用isprime[i]来表示i的最小质因子,可能用mod比较慢
}
}
}
在break那一行,有的人会用
if(i % prime[j]==0) break;
不过也可以通过isprime[i]保存i最小的质因子来与prime[j]做比较。
但不管怎么写,我人认为最重要的就是含break的那个语句
不过,仅仅筛素数就显得线性筛不是那么必要。
线性筛最科学的战场——求积性函数
作为蒟蒻,我以欧拉函数来举例:
先粗浅地看一下代码
void find_prime(int n)
{
memset(isprime,0,sizeof(isprime));
sp = 0;
for(int i = 2;i <= n;i++)
{
if(!isprime[i])
{
prime[++sp] = i;
isprime[i] = i;
phi[i] = i-1;//①
}
for(int j = 1;j <= sp && i * prime[j] <= n;j++) {
isprime[i*prime[j]] = prime[j];
if(prime[j] >= isprime[i]) {
phi[i*prime[j]] = phi[i]*prime[j];//②
break;
}
phi[i*prime[j]] = phi[i]*(prime[j]-1);//③
}
}
}
上述的五点:1表明每个数值被算一次。2解释了①。3、4、5解释了②和③。
还有,本文参考:http://www.cnblogs.com/zhuohan123/p/3233011.html
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章