欧拉函数和线性筛 学习笔记

参考资料:

oiwik欧拉函数https://oi-wiki.org/math/number-theory/euler/

  筛法https://oi-wiki.org/math/number-theory/sieve/

  筛法求欧拉函数https://oi-wiki.org/math/number-theory/sieve/#_8

 复习时看oiwiki就很好

欧拉函数 φ(n)(推荐看oiwiki)

    4条性质:2条自身,1条求自己,1条求n   

    sqrt n求欧拉函数:

// C++ Version
int euler_phi(int n) {
  int ans = n;
  for (int i = 2; i * i <= n; i++)//注意不要从1开始否则会死循环,
    if (n % i == 0) {
      ans = ans / i * (i - 1);
      while (n % i == 0) n /= i;
    }
  if (n > 1) ans = ans / n * (n - 1);//不要漏
  return ans;
}

     例题:P2303 [SDOI2012] Longge 的问题

      题解:想到对于n的一个因数x,会有多少对答案的贡献,即1~n有多少数y,满足gcd(y,n)=x,设t(x)为因数x对答案的贡献,即,令j=i/x,则原式相当于, 则答案为。因数可以O(sqrt n)枚举出,φ(x)也可以O(sqrt n)算出,故时间复杂度为O(因数个数 *  sqrt n) 

 1 #include<iostream>
 2 #include<cstdio>
 3 
 4 using namespace std;
 5 
 6 long long n,ans;
 7 
 8 inline int phi(long long x)
 9 {
10     long long ret=x;
11     for(long long i=2;i*i<=x;++i)
12         if(x%i==0)
13         {
14             ret=ret/i*(i-1);
15             while(x%i==0)
16                 x/=i;
17         }
18     if(x>1)
19         ret=ret/x*(x-1);
20     return ret;
21 }
22 
23 int main()
24 {
25     scanf("%lld",&n);
26     long long i;
27     for(i=1;i*i<n;++i)//完全平方数特殊处理 防重
28         if(n%i==0)
29             ans+=i*phi(n/i)+n/i*phi(i);
30     if(i*i==n)
31         ans+=i*phi(i);
32     cout<<ans;
33     return 0;
34 }
AC代码

      (复杂的式子就是要写下来化简才好嘛)

    2、计算一列数1~n的欧拉函数:

      O(n)线性筛法(见下)

 

线性筛:

    核心:用每个数尝试以最小质因数的根据筛掉合数。每个合数只会被最小质因数筛掉一次。

      对当前i用目前的质数筛,直到当前质数包含在i内后筛完停止。否则再继续筛的话,筛到的合数的最小质因数就不是枚举的质数,而是i内的那个小质因数了。由于目前的质数是扫进来的,故一定小于i,且i的质因数都包含在目前的质数内。复杂度为O(n)。

    核心代码:

void GetPrime(int n)//筛到n
{
    memset(isPrime, 1, sizeof(isPrime));
    //以“每个数都是素数”为初始状态,逐个删去
    isPrime[1] = 0;//1不是素数
    for(int i = 2; i <= n; i++)
    {
        if(isPrime[i])
            Prime[++cnt] = i;
        for(int j = 1; j <= cnt && i*Prime[j] <= n/*不超上限*/; j++) 
        {
            isPrime[i*Prime[j]] = 0;
            if(i % Prime[j] == 0)
                break;
        }
    }
}

  

    筛法求欧拉函数:i和p根据整除关系分两类。

  

 

posted @ 2022-04-25 11:27  千叶繁华  阅读(24)  评论(0编辑  收藏  举报