筛法,欧拉函数表,莫比乌斯函数表,积性函数

来源:互联网 发布:网络电视卡顿怎么办 编辑:程序博客网 时间:2024/05/20 16:11

看来别人的博客,对筛法有了新的认识

1.Eratosthenes筛法(Sieve of Eratosthenes)

这是一种简单检定素数的算法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛法(sieve of Eratosthenes)。

也就是我们常用的素数筛选法

我们第一次遇见的便是素数,然后拿一个素数可以把和此素数相关的合数筛选出来

bool book[N];int prime[N];int res;void  eratosthenes_sieve(){res=0;memset(book,false,sizeof(book));for(int i=2;i<N;i++){if(!book[i]){prime[res++]=i;for(int j=28i;j<N;j+=i)book[j]=true;}}}

2.Euler筛法(Sieve of Euler)

Eratosthenes筛法每次用一个素数去筛选,比如6被2,3筛选了两次,显然浪费了时间
如果把每个数都只被自己最小的素因子遍历那么就会减小时间复杂度
这也就是欧拉筛法

bool book[N];int prime[N];int res;void  eratosthenes_sieve(){res=0;memset(book,false,sizeof(book));for(int i=2;i<N;i++){if(!book[i]) prime[res++]=i;for(int j=0;i*prime[j]<N&&j<res;j++){book[i*prime[j]]=true;if(i%prime[j]==0)break;}}}

很多相关的积性函数都可以用欧拉线性筛法得到


φ(n) -            欧拉函数
μ(n) -            莫比乌斯函数,关于非平方数的质因子数目
gcd(n,k) -     最大公因子,当k固定的情况
d(n) -            n的正因子数目
σ(n) -            n的所有正因子之和
σk(n) -          因子函数,n的所有正因子的k次幂之和,当中k可为任何复数。
1(n) -            不变的函数,定义为 1(n) = 1 (完全积性)
Id(n) -           单位函数,定义为 Id(n) = n(完全积性)
Idk(n) -         幂函数,对于任何复数、实数k,定义为Idk(n) = n^k (完全积性)
ε(n) -            定义为:若n = 1,ε(n)=1;若 n > 1,ε(n)=0。别称为“对于狄利克雷卷积的乘法单位”(完全积性)
λ(n) -            刘维尔函数,关于能整除n的质因子的数目
γ(n),             定义为γ(n)=(-1)^ω(n),在此加性函数ω(n)是不同能整除n的质数的数目
另外,           所有狄利克雷特征均是完全积性的[1] 


欧拉函数


const int N=1100;const int maxn=1009;  int prime[N],euler[N],ans[N];  int res;  void  eratosthenes_sieve()  {      res=0;      memset(euler,0,sizeof(euler));      ans[1]=3;     for(int i=2;i<maxn;i++)      {        if(euler[i]==0)            prime[res++]=i,euler[i]=i-1;        for(int j=0;j<res&&i*prime[j]<maxn;j++)        {            if(i%prime[j]==0)            {                euler[i*prime[j]]=euler[i]*prime[j];                break;            }            euler[i*prime[j]]=euler[i]*(prime[j]-1);        }  ans[i]=ans[i-1]+(2*euler[i]) ;    }  }



emmmmm.......就目前来看好像积性函数都能用线性筛,我也不知道是不是,希望有大佬能留言区告知一下

分清一下     i%prime[j]==0  与    i%prime[j]!=0的情况讨论

而这里就是思考的所在

n的正因子数目

bool book[N];int prime[N],d[maxn],temp[maxn];int res;void  eratosthenes_sieve(){res=0;memset(book,false,sizeof(book));     for(int i=2;i<maxn;i++)    {      if(!temp[i])            prime[res++]=i,d[i]=2;      for(int j=0;j<res&&i*prime[j]<maxn;j++)      {          if(i%prime[j]==0)          {              temp[i*prime[j]]=prime[j]*temp[i];              d[i*prime[j]]=d[i/temp[i]]*(d[temp[i]]+1);              break;          }           temp[i*prime[j]]=prime[j];          d[i*prime[j]]=2*d[i];      }}

sum(d)=p|dμ(dp)

const int maxn = 10000010;  int prime[maxn],mu[maxn],sum[maxn];  bool check[maxn];  void Mobius(){      memset(check,false,sizeof(check));      mu[1] = 1;      prime[0] = 0;     for(int i=2;i<maxn;i++){          if(!check[i]){              mu[i] = -1;              sum[i] = 1;              prime[++prime[0]] = i;          }          for(int j=1;j<=prime[0];j++){              if(i*prime[j] >= maxn)  break;              check[i*prime[j]] = true;              if(i % prime[j]){                  mu[i*prime[j]] = -mu[i];                  sum[i*prime[j]] = mu[i] - sum[i];              }              else{                  mu[i*prime[j]] = 0;                  sum[i*prime[j]] = mu[i];                  break;              }          }      }  }