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

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

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];
      }
}

s u m ( 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;  
            }  
        }  
    }  
} 









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值