欧拉函数&欧拉定理

欧拉定理其实就是这么一句话:

gcd(a,n)=1aφ(n)1(modn)

然后欧拉函数φ(n)表示小于等于n的数中和n互质的数的个数
性质:
1.积性函数:
gcd(a,b)=1φ(ab)=φ(a)φ(b)
从这个定义和组合意义上来说,φ这个函数显然是积性的
因为和ab互质是和a,b同时互质的充要条件,稍微思考不难理解
对于积性函数f,总有gcd(a,b)=1f(ab)=f(a)f(b)
这是定义的逆用
2.n=d|nφ(d)

3.若n=pk,p为质数,则φ(n)=pkpk1
如果一个数和n不互质,那么p为两者最大公约数的约数,反之显然。
所以我们只需要找到n以内有多少个数被p整除,减一下就有了

单个数的求法:
考虑把p分解质因数,然后用性质三可以知道每个φ(pk)
根据积性函数的性质,φ(n)=φ((piki))=φ(piki)

蓝书上还有一个公式可以直接用

点击查看代码
int euler_phi(int n) {
  int m = int(sqrt(n + 0.5));
  int ans = n;
  for (int i = 2; i <= m; i++)
    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;
}

如果涉及到一堆数,建议使用线性筛,主要使用性质一:

点击查看代码
// C++ Version
void pre() {
  memset(is_prime, 1, sizeof(is_prime));
  int cnt = 0;
  is_prime[1] = 0;
  phi[1] = 1;
  for (int i = 2; i <= 5000000; i++) {
    if (is_prime[i]) {
      prime[++cnt] = i;
      phi[i] = i - 1;
    }
    for (int j = 1; j <= cnt && i * prime[j] <= 5000000; j++) {
      is_prime[i * prime[j]] = 0;
      if (i % prime[j])
        phi[i * prime[j]] = phi[i] * phi[prime[j]];
      else {
        phi[i * prime[j]] = phi[i] * prime[j];
        break;
      }
    }
  }
}

低于线性的积性函数求法不在NOIPtg范围以内
但是也不是不学
顺便说一句,见到积性函数求一堆值想线性筛
~~别tmd再拿个埃筛硬干被卡内存痛失100pts了~

posted @   2K22  阅读(130)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示