欧拉定理

欧拉定理(Euler's Totient Theorem)

一、核心思想:指数的周期性

在模 \(n\) 运算上,不断地用一个数 \(a\) 去乘以自己时(即 \(a, a^2, a^3, \dots\)),会发现结果会呈现出周期性循环

欧拉定理对这个循环的长度给出了一个明确的结论:

只要 \(a\)\(n\) 互质,那么 \(a\)\(\phi(n)\) 次方模 \(n\) 的结果,必然是 \(1\)

这里的 \(\phi(n)\) 就是欧拉函数。

二、定理的正式表述

如果整数 \(a\) 和 正整数 \(n\) 满足 \(\gcd(a,n)=1\)(即它们互质),那么:\(a^{\phi(n)} \equiv 1 \pmod{n}\)

这个定理是费马小定理的推广。当 \(n\) 是一个质数 \(p\) 时,\(\phi(p) = p-1\),定理就变成了 \(a^{p-1} \equiv 1 \pmod{p}\),这正是费马小定理。

三、应用:降幂

这个定理的厉害之处在于,能把很大的指数给降下来。既然 $a^{\phi(n)} 等于 \(1\),那么 \(a\)\(k \cdot \phi(n)\) 次方也等于 \(1\)。这意味着指数 \(b\) 可以对 \(\phi(n)\) 取模。

所以,计算 \(a^b \bmod n\) 时,可以把它简化为:\(a^b \equiv a^{b \bmod \phi(n)} \pmod{n}\)

例子:计算 \(3^{100} \bmod 7\)

  1. 检查条件\(\gcd(3,7)=1\),互质。满足条件。
  2. 计算 \(\phi\)\(7\) 是质数,\(\phi(7)=7-1=6\)
  3. 降幂:指数 \(100\) 可以对 \(6\) 取模。\(100 \bmod 6 = 4\)
  4. 简化问题:原问题等价于计算 \(3^4 \bmod 7\)
  5. 计算\(3^4 = 81\)\(81 \div 7 = 11 \cdots 4\)
  6. 答案\(3^{100} \bmod 7 = 4\)

扩展欧拉定理(Extended Euler's Theorem)

一、为什么需要“扩展”?

欧拉定理有一个严格的限制:\(a\)\(n\) 必须互质。那如果不互质怎么办?比如计算 \(6^{100} \bmod 10\)\(\gcd(6,10)=2\),欧拉定理就没法直接用了。

扩展欧拉定理就是来解决这个问题的。它是一个更通用的版本,\(a\)\(n\) 没有任何限制

二、定理的正式表述

对于任意整数 \(a\) 和正整数 \(n\),分情况讨论指数 \(b\)

  1. \(b \lt \phi(n)\) 时:
  • 指数 \(b\) 还不够大,可能还没进入“循环节”。
  • 这时候不能降幂,老老实实直接计算。
  1. \(b \ge \phi(n)\) 时:
  • 指数 \(b\) 足够大,保证它已经进入了数字的循环节。
  • 这时候就可以安全地降幂了,但公式稍微有点不同。
  • \(a^b \equiv a^{b \bmod \phi(n) + \phi(n)} \pmod{n}\)

注意这个 \(+ \phi(n)\)。这是扩展欧拉定理的精髓,也是和标准欧拉定理唯一的区别。

为什么要 \(+ \phi(n)\)?这是一个“安全措施”。因为当 \(a\)\(n\) 不互质时,幂的循环可能不会从 \(a^0=1\) 开始。前面可能有一小段“尾巴”不参与循环。\(b \bmod \phi(n)\) 可能会得到一个很小的数,这可能会跳回到“尾巴”上。而 \(b \bmod \phi(n) + \phi(n)\) 保证了新的指数一定大于等于 \(\phi(n)\),安全地留在循环节内。

例子:计算 \(6^{100} \bmod 10\)

  1. 检查条件\(\gcd(6,10)=2\),不互质。必须用扩展欧拉定理。
  2. 计算 \(\phi\)\(\phi(10)= 10 \times (1-1/2) \times (1-1/5) = 4\)
  3. 比较指数:指数 \(b=100\)\(\phi(10)=4\)。因为 \(100 \ge 4\),适用第二种情况。
  4. 降幂\(100 \bmod 4 = 0\)。新的指数是 \(0 + \phi(10) = 4\)
  5. 简化问题:原问题等价于计算 \(6^4 \bmod 10\)
  6. 计算\(6^1=6, 6^2=36 \equiv 6, 6^3 \equiv \dots 6\)\(6\) 的任意正整数次幂模 \(10\) 都是 \(6\)。所以 \(6^4 \bmod 10 = 6\)
  7. 答案\(6^{100} \bmod 10 = 6\)

习题:P5091 【模板】扩展欧拉定理

解题思路

先求 \(\phi(m)\),然后求 \(b \bmod \phi(m)\),在拼数的过程中取余来求。

中间判断一下拼数的过程中是否出现了 \(\ge \phi(m)\) 的情况。如果没出现,就是 \(b \lt \phi(m)\) 的情况,也就是要求 \(a^b\),否则最后是求 \(a^{b \bmod \phi(m) + \phi(m)}\)

参考代码
#include <cstdio>
const int N = 20000005;
char s[N];
int calcPhi(int x) {
    int res = x;
    int i = 2;
    while (i * i <= x) {
        if (x % i == 0) {
            res = res / i * (i - 1);
            while (x % i == 0) x /= i;
        }
        i++;
    }
    if (x > 1) res = res / x * (x - 1);
    return res;
}
int qpow(int x, int y, int mod) {
    int res = 1;
    while (y > 0) {
        if (y & 1) res = 1ll * res * x % mod;
        x = 1ll * x * x % mod;
        y >>= 1;
    }
    return res;
}
int main()
{
    int a, m; scanf("%d%d%s", &a, &m, s);
    int phi = calcPhi(m);
    int b = 0;
    bool big = false;
    for (int i = 0; s[i]; i++) {
        b = b * 10 + s[i] - '0';
        if (b >= phi) {
            b %= phi; big = true;
        }
    }
    if (big) b += phi;
    printf("%d\n", qpow(a, b, m));
    return 0;
}
posted @ 2025-07-14 10:28  RonChen  阅读(277)  评论(0)    收藏  举报