• 线性(欧拉)筛&欧拉函数


    ## 线性筛法 what is 线性筛??就是基于最基本的筛法的优化。 在基础的筛法上,我们发现有的数字会被重复筛,例如6既会被2枚举到也会被3枚举到,必然有重复运算。 我们的做法就是让每一个数的最小因数筛。 **$FOR$ $EXAMPLE:$** 有一个数$2 * 2 * 3 * 5$ 有另一个数 $3 * 3 * 3* 5$ 那么第一个数枚举到3的话,筛到的数字是$2 * 2 * 3 * 3 * 5$ 但是在第二个数字再次枚举的时候 枚举到2时 也会枚举到$2 * 2 * 3 * 3 * 5$ 因此,维护这个最小质因数即可。 怎么维护?? 当$i$ $mod$ $这个质因数$ $=0$ 说明是质因数,第一次枚举到就要$break$,这样就保证了一定会被最小素因数给筛。 ```cpp #include using namespace std; int main() { int n,cnt=0; int prime[10000]={};//用来存储素数 int Vis[10000]={};//用来判断是否是素数 cin>>n; for (int i=2;i<=n;i++) { if (Vis[i]==0) prime[++cnt]=i;//如果没有被标记过 for (int j=1;j<=cnt&&i*prime[j]<=n;j++)//用i去乘上每一个已经求过的素数 { Vis[i*prime[j]]=1;//标记素数 if (i%prime[j]==0) break;//下面再解释 } } for (int i=2;i<=n;i++) if (Vis[i]==0) cout<

    一、欧拉函数概念

    欧拉函数,是表示1~n中与n互质的元素的个数,记为\(φ(n)\)

    二、性质

    • 如果n为某一素数p,显然\(φ(p)\)为p-1
    • 如果n为某一素数的幂次,那么: $$\phi(pa)=(p-1)*p {a-1}$$
      我们可以来推导次函数的求法
      我们先将n分解质因数得:

    \[n=a1^{b1}*a2^{b2}*a3^{b3}*……*ak^{bk} \]

    因为φ(n)求的是与n互质的数的个数,所以其中不能有n的因数,即不能出现a1,a2,a3……ak的倍数。
    那么我们来转换思路,n个数之中存在多少个a1的倍数,多少个a2的倍数……多少个ak的倍数呢?
    显然有n/a1个a1的倍数,n/a2个a2的倍数……有n/ak个ak的倍数。

    所以\(φ(n)=n-\frac{1}{a1} -\frac{1}{a2}-\frac{1}{a3}-……-\frac{1}{ak}\)
    将n提取出来得到:

    \[φ(n)=n*(1-\frac{1}{a1})*(1-\frac{1}{a2})*(1-\frac{1}{a3})*……*(1-\frac{1}{ak}) \]

    于是欧拉函数的公式就这么推导出来了

    还有如下性质:

    • 如果i mod p=0,那么\(φ(i*p)=p*φ(i)\)
      证明:
      对于公式$$φ(1)=n(1-\frac{1}{a1})(1-\frac{1}{a2})(1-\frac{1}{a3})……*(1-\frac{1}{ak})$$
      得到

      \[φ(n)=n*p*(1-\frac{1}{a1})*(1-\frac{1}{a2})*(1-\frac{1}{a3})*……*(1-\frac{1}{ak}) \]

      因为p已经是i的因数,后半部分不需要添加
      因此得证。

    • 函数的积性,\(φ(i*j)=φ(i)*φ(j)\)

    • 如果i mod p≠0,那么\(φ(i*p)=φ(i)*(p-1)\)
      根据

    \[φ(n)=n*(1-\frac{1}{a1})*(1-\frac{1}{a2})*(1-\frac{1}{a3})*……*(1-\frac{1}{ak}) \]

    得到

    \[φ(n)=n*p*(1-\frac{1}{a1})*(1-\frac{1}{a2})*(1-\frac{1}{a3})*……*(1-\frac{1}{ak})*(1-\frac{1}{p}) \]

    因为p不是i的因数,因此最后要加上\((1-\frac{n}{ak})\)部分。
    证明完成。

    三、求法

    下面给两种求法。

    \(1\).公式法

    根据公式\(φ(n)=n*(1-\frac{1}{a1})*(1-\frac{1}{a2})*(1-\frac{1}{a3})*……*(1-\frac{1}{ak})*(1-\frac{1}{p})\)

    inline LL eular(LL x)
    {
        LL sum=x,y=x;
        for (LL i=2;i*i<=y;++i)
        {
            if (x%i!=0) continue;
            sum=sum/i*(i-1); 
            while (x%i==0) x/=i;
        }
        if (x>=2) sum=sum/x*(x-1);
        return sum;
    }
    //公式求x欧拉函数 
    

    \(2\).线性筛求欧拉函数

    根据三条性质推导即可。
    线性筛中每一个数字最多只会被筛一次,因此正好可以对每一个数字求欧拉函数。
    线性筛正好是由小的数字筛到大的数字 or 正好是指数
    前者用后两条性质 后者用第一条性质即可。
    三条性质如下:

    • 如果n为某一素数的幂次,那么: \(\phi(p^a)=(p-1)*p^ {a-1}\)
    • 如果i mod p=0,那么\(φ(i*p)=p*φ(i)\)
    • 如果i mod p≠0,那么\(φ(i*p)=φ(i)*(p-1)\)
    inline void findphi(void)
    {
        phi[1]=1,prm[1]=0;
        for (LL i=2;i<=n;++i)
        {
            if (!v[i]) { prm[++cnt]=i, phi[i]=i-1; }
            for (LL j=1;j<=cnt && i*prm[j]<=n;++j)
            {
                v[i*prm[j]]=1;
                if (i%prm[j]==0) { phi[i*prm[j]]=phi[i]*prm[j]; break; }
                if (i%prm[j]!=0) phi[i*prm[j]]=phi[i]*(prm[j]-1);	
            }	
        }
        return; 
    } 
    

    后记

    部分参考hkh大佬的博客。
    在此表示感谢!
    如有纰漏请读者指正!
    <\font>

  • 相关阅读:
    13自下而上语法分析
    12 递归下降语法分析
    LL(1)文法的判断,递归下降分析程序
    消除左递归
    作业4 .K均值算法--应用
    作业3 K均值算法
    作业2 机器学习相关数学基础
    作业1 机器学习概述
    作业15 语法制导的语义翻译
    作业14:算符优先分析
  • 原文地址:https://www.cnblogs.com/pigzhouyb/p/10119722.html
Copyright © 2020-2023  润新知