线性筛欧拉函数(莫比乌斯反演第二弹)

其实欧拉函数的用处还有很多,这里介绍欧拉函数的定义,其递推式的证明以及其求法

欧拉函数

我们先来认识一下欧拉函数的定义以及递推方法。
定义:欧拉函数phi(n)表示的是在1~n范围内与n互质的数的个数。
递推方法:
若n为质数,则phi(n)=n-1;
若n不为质数,则一定存在一个质数p,使得p|n,不妨设n=m*p(m为一个整数),则可做如下分类:
1) 若m%p=0,则phi(n)=phi(m)*p;
2) 若m%p≠0,则phi(n)=phi(m)*(p-1);

欧拉函数递推式的证明

我们还是分类讨论:

  1. 当m%p=0时,对于b(1≤b≤n),若b满足gcd(b,m)=1,则有gcd(b,q)=1,进而可以推出gcd(b,n)=1,即若b与m互质,则b就与n互质。若b不满足gcd(b,m)=1,则gcd(b,n)≠1。
    即对于b(1≤b≤n),要使b与n互质,当且仅当b与m互质。
    对于n有n=m*p,我们不妨把1~n分为p个集合 [(m*(i-1),m*i]}(1≤i≤q)
    则每个处于1~n的数b都可以用b=m*(i-1)+j表示, 则有gcd(b,m)=gcd(m*(i-1)+j,m)=gcd(m,(m*(i-1)+j)%m)=gcd(m,j);
    这也可以说明上述分组的意义,即对于每组的数,与m(即与n)互质的数的数都是相等的,故可以得出 phi(n)=phi(m)*p;(p组数)
  2. 当m%p≠0时,对于b(1≤b≤n),若b满足gcd(b,p)≠1(即gcd(b,p)=p,因为p是质数),且gcd(b,m)=1,则gcd(b,n)=p;
    这可证明对于b(1≤b≤n),即使有gcd(b,m)=1,也不一定有gcd(b,n)=1。而若b不满足gcd(b,m)=1,那就如上文所说的那样就啥都免谈了。
    那么,既然这样我们该怎么办呢?
    不妨先假设对于b(1≤b≤n),若b满足gcd(b,m)=1,b就满足gcd(b,n)=1,那么这样算出来的phi(n)就和上一种情况一样(b与m,q都互质),则phi(n)=phi(m)*p。
    但是,事情并没有像上一种情况么简单。因为在上一种情况中,只要b与m互质,b就与p互质,而在这一种情况中b与m互质不代表b与p互质,那么我们该怎么办呢?
    对,把不符合条件(与m互质,与p不互质)的数的数目减去即可。
    因为p为一个质数,所以与p不互质的数只可能是p的倍数,又因为n=p*m,在[1,n]内,p的倍数有m个,不妨设b=p*i(1≤i≤m),当且仅当gcd(i,m)=1时,gcd(b,m)=1。
    由此,我们可以得知不符合条件(与m互质,与p不互质)的数的数目就是[1,m]中与m互质的数的个数,也就是phi(m)。我们只需在原有答案的基础上减去phi(m)就可以得到phi(n)的值。
    即phi(n)=phi(m)*p-phi(m)=phi(m)*(p-1);

线性筛欧拉函数

理解了上面的内容后,线性筛欧拉函数就不难了。直接套在线性筛素数的板子上就行了,因为你会发现这两者的求法有着惊人的相似处。
如果线性筛素数不会的话 戳这里

a[1]=1;pri=0;
for (int i=2;i<=n;i++)
{
    if (!a[i])
    {
        prime[++pri]=i;
        phi(i)=i-1;
    }
    for (int j=1;j<=pri && i*prime[j]<=n;j++)
    {
        a[i*prime[j]]=1;
        if (!(i%prime[j]))
        {
            phi[i*prime[j]]=phi[i]*prime[j];
            break;
        }
        phi[i*prime[j]]=phi[i]*(prime[j]-1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值