求欧拉函数值 && 打表O(n)

在数论,对正整数n,欧拉函数是1~n的数中与n互质的数的数目,我们记为 φ ( n ) φ(n) φ(n),(后面欧拉定理中会用到)。此函数以其首名研究者欧拉命名。例如 φ ( 8 ) = 4 φ(8)=4 φ(8)=4,因为1,3,5,7均和8互质。

φ ( n ) φ(n) φ(n)求解公式:
现假设 n n n r r r个质因子p1、p2、p3、、、pr,则:

215-08-04/55c058b16129e

φ ( n ) = n ∏ i = 1 r ( 1 − 1 p   i   ) φ(n)=n\prod_{i=1}^r (1-\frac{1}{p~i~}) φ(n)=ni=1r(1p i 1)

欧拉函数的两个性质:来自欧拉函数及其证明(这两个性质可以推出上面的公式)

  • 欧拉函数既然是积性函数,就说明如果n可以分解成两个互质的整数之积, n = p 1 × p 2 n = p1 × p2 n=p1×p2,则
    φ ( n ) = φ ( p 1 p 2 ) = φ ( p 1 ) φ ( p 2 ) φ(n) = φ(p1p2) = φ(p1)φ(p2) φ(n)=φ(p1p2)=φ(p1)φ(p2)
  • 如果n是质数的某一个次方,即n = pk (p为质数,k为大于等于1的整数),则
    φ ( n ) = p k − p k − 1 = p k − 1 ∗ ( p − 1 ) φ(n) =p^k- p^ {k-1}=p^{k-1}*(p-1) φ(n)=pkpk1=pk1(p1)
1、单独求某个欧拉函数值代码: O ( n ) O(\sqrt{n}) O(n )
int fn(int x)
{
    int ans=x;
    for(int i=2; i<=sqrt(x); i++)
    {
        if(x%i==0)
        {
            ans-=ans/i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        ans-=ans/x;
    return ans;
}

2、埃氏筛、欧拉筛

   ⟹    \implies 质数打表———埃氏筛&&欧拉筛

2.1 求1~n的欧拉函数值: O ( n l o g l o g n ) O(nloglogn) O(nloglogn)
//埃氏筛法中每个合数会被它的每个质因子筛一遍,就完美地求出欧拉函数值了

bool vis[manx];
void make_prime(int n)
{
     memset(vis,0,sizeof(vis));
     vis[0]=vis[1]=1;
     for(int i=1;i<=n;i++)
          ans[i]=i;
     for(int i=2;i<=n;i++)
     {
          if(!vis[i])
          {
               for(int j=i;j<=n;j+=i)
               {
                    vis[j]=1;
                    ans[j]=ans[j]*(i-1)/i;//主角在这里
               }
          }
     }
}

2.2 求1~n的欧拉函数值: O ( n ) O(n) O(n)
原理:以下证明来自欧拉线性筛(筛质数,求欧拉函数)

那么,为了求可以在可以在线性时间内求出来所有的欧拉函数,需要事先知道三个性质:
对于一个质数 p p p:
性质1: φ ( p ) = p − 1 φ( p)=p-1 φ(p)=p1;
因为p为质数,而从1到 p p p,只有 p p p p p p自本身不互质,其余的 ( p − 1 ) (p-1) (p1)个数字都与 p p p互质,因此得出性质1;
性质2:对于 i i i% p = = 0 , φ ( i ∗ p ) = p ∗ φ ( i ) p==0 , φ(i * p)=p * φ(i) p==0,φ(ip)=pφ(i);
性质3:对于 i i i% p ! = 0 p ! = 0 p!=0, φ ( i ∗ p ) = φ ( i ) ∗ ( p − 1 ) ; φ (i * p) = φ(i) * (p-1); φ(ip)=φ(i)(p1);
利用了欧拉函数的积性。而又通过性质1可知, p − 1 = φ ( p ) p-1=φ( p) p1=φ(p),因此 φ ( i ∗ p ) = φ ( i ) ( p − 1 ) = φ ( i ) ∗ φ ( p ) φ(i*p)=φ(i)(p-1)=φ(i)*φ ( p) φ(ip)=φ(i)(p1)=φ(i)φ(p);
这个,本人才疏学浅,看了各种证明,但还是不明白性质2,性质3是怎么得出来的,所以先当作结论记住吧。
知道了这三个结论之后,在配合欧拉筛筛质数,就可以得出范围内所有的数字的欧拉函数。


2020.7.19对性质2的理解:对于 i % p = = 0 i\%p==0 i%p==0(即p也是i的因子),与i互质的数肯定与 i*p互质。比如i=35,p=5时,与i互质的数有1,2,3,4,6…那么这些数肯定也与35 *5互质,而且将这些数分别加上35(或35 *2,35 *3,35 *4)后可以发现它们还是与35 *5互质,所以与35 *5的数的个数为φ(35) *5


代码:

void make_prime(int n)
{
    int cou=0,ans[manx];
    memset(prime,0,sizeof(prime));
    memset(vis,0,sizeof(vis));
    vis[0]=vis[1]=1;
    for(int i=2; i<=n; i++)
    {
        if(!vis[i])
        {
            prime[cou++]=i;
            ans[i]=i-1;//改动部分1(对应性质1)
        }
        for(int j=0; j<cou; j++)
        {
            if(i*prime[j]>n)
                break;
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                ans[i*prime[j]]=ans[i]*prime[j];//改动部分2(对应性质2)
                break;
            }
            else
                ans[i*prime[j]]=ans[i]*ans[prime[j]];//改动部分3(对应性质3)
                //或者写成ans[i*prime[j]]=ans[i]*(prime[j]-1);
        }
    }
}

例题:Farey Sequence
感想:质因子是个神奇的存在

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值