zoukankan      html  css  js  c++  java
  • 欧拉筛(线性筛)求莫比乌斯函数μ

    欧拉筛


    筛法我们肯定都不陌生,用来求一定序列内素数个数的方法麻,但在学习完埃氏筛法后(如果没学过可以去学一下再看),我们发现它似乎做了很多多余的操作,一个数会被他的质所有筛

    一遍,但我们本质上筛一遍就够了,所以我们有没有什么方法去优化它呢?欧拉筛随之而出,欧拉筛的特点便是一个数只会被它的最小质因子筛一遍,其它质因子不会筛它,这便大大提高了时

    间效率

    代码如下

    (懒的不想写便把这个博客里的代码搬了一下)

    for( int i=2;i<=n;i++ ) {
    	if( !death[i] )
    		primelist[++tail] = i;//record this new prime
    	for( int k=1;k<=tail;k++ ) {
    		if( primelist[k]*i > n ) break;
    		death[primelist[k]*i] = 1;
    		if( i%primelist[k] == 0 ) break;//!!!
    	}	
    
    }
    

    death为我们的标记数组

    欧拉筛相比埃氏筛的优点便在与if( i%primelist[k] == 0 ) break;这一句

    当primelist[k]>primelistk1

    时,因为primelist[k1]是i的最小质因子,所以它也是primelist[k]*i的最小质因子

    所以primelist[k]i会由primelist[k1]某个i更新出来,所以当primelist[k]>primelist[ k1 ]时我们break;

    将拒绝重复计算,而i*比他最小质因子小的质数,则是在更新以该质数为最小质因子的合数。

    利用线性筛求莫比乌斯函数

    我们来做一点小练习

    利用线性筛求莫比乌斯函数

        mu[1]=1;
        for (int i=2;i<=10000000;i++) {
            if (!flag[i]) prime[++cnt]=i,mu[i]=-1;
            for (int j=1;j<=cnt&&i*prime[j]<=10000000;j++) {
                flag[i*prime[j]]=1;
                if (i%prime[j]==0) break;
                mu[i*prime[j]]=-mu[i];
            }
        }
    

    介绍到这里啦,完结撒花!

  • 相关阅读:
    Google Analytics:为链接点击设定事件追踪的方法
    HTTP状态码大全
    jquery插件的编写
    2016.2.27日(开学)学习总结
    关于单文件上传的封装
    单文件的文件上传详细解释
    php中对象的串行化
    PDO的事物处理机制
    MySQL操作类的封装(PHP)
    smarty的简单介绍
  • 原文地址:https://www.cnblogs.com/rpup/p/13557308.html
Copyright © 2011-2022 走看看