GESP2025年3月认证C++五级( 第三部分编程题(2、原根判断))


🏰《魔法钥匙的考验》


一、🎮 故事背景

在一个神秘王国里,有一扇"超级宝库大门"🔐

  • 门的编号是一个质数 p

  • 小勇士拿着一把钥匙 a

👉 现在要判断:

🔑 a 能不能成为这扇门的"万能钥匙"(原根)?


二、🎯 什么是"原根"?

(1)👉 如果 a 是原根,那么:

复制代码
a^1 mod p
a^2 mod p
a^3 mod p
...
a^(p-1) mod p

👉 会把所有 1~p-1 全部走一遍(不重复!)


(2)🧠 直观理解

就像:

🎡 一个转盘,有 p-1 个位置

👉 每次乘 a,相当于"转一步"

如果:

✔ 能走遍所有位置 → 原根

❌ 有位置没走到 → 不是


(3)💡词条详细解释

原根是数论中的一个重要概念,尤其在模运算和密码学中有广泛应用。以下是关于原根的详细解释:

定义

设 m 是一个正整数,a 是一个与 m 互质的整数(即 gcd(a,m)=1)。如果 a 的幂次模 m 的结果能够生成所有与 m 互质的数,则称 a 为模 m 的原根。具体来说:

  • 集合 {a0,a1,a2,...,aϕ(m)−1} 模 m 的余数恰好覆盖所有与 m 互质的数(即模 m 的简化剩余系)。
  • 这里 ϕ(m) 是欧拉函数,表示小于 m 且与 m 互质的正整数的个数。

关键性质

  1. 存在性:并非所有正整数 m 都有原根。原根存在的充分必要条件是:

    • m=2,4;
    • m=pk(其中 p 是奇素数,k≥1);
    • m=2pk(其中 p 是奇素数,k≥1)。
  2. 阶数 :原根的阶(即最小的正整数 k 使得 ak≡1modm)等于 ϕ(m)。因此,原根是模 m 的本原根

  3. 数量:若模 m 存在原根,则原根的个数为 ϕ(ϕ(m))。例如:

    • 模 7 的原根有 2 个(3 和 5),因为 ϕ(6)=2。
    • 模 11 的原根有 4 个(2,6,7,8),因为 ϕ(10)=4。

例子

  1. 模 7 的原根
    • ϕ(7)=6,与 7 互质的数为 {1,2,3,4,5,6}。

    • 计算 3 的幂次模 7:

3^0≡1,3^1≡3,3^2≡2,3^3≡6,3^4≡4,3^5≡5mod7

结果覆盖所有简化剩余系,因此 3 是模 7 的原根。同理, 5 也是原根。


  1. 模 8 的原根
  • ϕ(8)=4,与 8 互质的数为 {1,3,5,7}。

  • 检查 3 的幂次:

3^0≡1,3^1≡3,3^2≡1mod8

无法覆盖所有简化剩余系,因此 3 不是原根。实际上,模 8 没有原根(因为 8 不满足存在原根的条件)。


应用

  1. 密码学:原根用于生成大素数模下的离散对数问题,是Diffie-Hellman密钥交换和ElGamal加密等协议的基础。
  2. 数论:原根与指数、指标等概念密切相关,用于解决同余方程和模运算问题。
  3. 随机数生成:原根的周期性可用于构造伪随机数序列。

如何寻找原根

寻找原根通常需要试算。对于模 p(素数),步骤如下:

  1. 计算 ϕ(p)=p−1,并分解 p−1 为质因数乘积:p−1=q1e1​​q2e2​​⋯qkek​​。

  2. 对每个候选数 a,检查是否满足:

a(p−1)/qi​≡1modp对所有i=1,2,...,k

若满足,则 a 是原根。

总结

原根是模运算中能够生成所有简化剩余系的"生成元",其存在性受模数形式的限制。它在密码学和数论中扮演核心角色,理解原根有助于深入掌握模运算和离散对数问题。


三、🧩 关键数学结论

我们不用真的去枚举所有幂(太慢❌)


1、💡 判定条件(核心🔥)

(1)设:

复制代码
φ(p) = p - 1

(2)把 p-1 分解质因数:

复制代码
p-1 = q1 × q2 × q3 × ...

(3)👉 只要检查:

复制代码
a^( (p-1)/qi ) mod p ≠ 1   (对所有质因子 qi)

(4)👉 全部成立 → ✔ 原根

👉 有一个成立为 1 → ❌ 不是


2、🧠 为什么?

👉 如果某次变成 1

说明:它"提前绕回来了",没有走完整圈


四、🪜 完整解题步骤


✅ Step 1:读入 a 和 p


✅ Step 2:计算 φ(p)

复制代码
φ(p) = p - 1

✅ Step 3:分解 φ(p)

👉 找出所有"质因子"

例如:

复制代码
p-1 = 12 = 2 × 2 × 3
→ 质因子:2 和 3

✅ Step 4:逐个检查

对每个质因子 q:

复制代码
检查:a^( (p-1)/q ) mod p

👉 如果出现:

复制代码
= 1

👉 直接判 ❌


✅ Step 5:全部通过

👉 输出:

复制代码
Yes

复制代码
No

五、⚡使用快速幂

(1)因为指数很大!

我们用:

👉 快速幂(递归或循环都行)


(2)💻 快速幂模板

复制代码
long long fastPow(long long a, long long b, long long mod) {
    long long res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

六、🧪 参考代码

复制代码
#include <bits/stdc++.h>
using namespace std;

// 快速幂
long long fastPow(long long a, long long b, long long mod) {
    long long res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

int main() {
    int T;
    cin >> T;

    while (T--) {
        long long a, p;
        cin >> a >> p;

        long long phi = p - 1;
        long long temp = phi;

        vector<long long> factors;

        // 分解质因子
        for (long long i = 2; i * i <= temp; i++) {
            if (temp % i == 0) {
                factors.push_back(i);
                while (temp % i == 0) temp /= i;
            }
        }
        if (temp > 1) factors.push_back(temp);

        bool ok = true;

        // 检查原根条件
        for (auto q : factors) {
            if (fastPow(a, phi / q, p) == 1) {
                ok = false;
                break;
            }
        }

        if (ok) cout << "Yes\n";
        else cout << "No\n";
    }

    return 0;
}

七、🎯 知识点总结:


🧠 ① 模型转化能力(最关键🔥)

👉 "看起来复杂的定义"

👉 → 转化成"几个幂运算判断"


🧠 ② 降维简化思维

👉 原本要检查 p-1 次

👉 现在只需要检查"质因子个数次"


🧠 ③ 快速幂(核心工具)

👉 所有:

  • 模运算

  • 指数很大

都可以用它!


相关推荐
Frostnova丶11 小时前
(18)LeetCode 73. 矩阵置零
算法·leetcode·矩阵
冻柠檬飞冰走茶11 小时前
PTA基础编程题目集 7-11 分段计算居民水费(C语言实现)
c语言·开发语言·算法
得物技术11 小时前
推荐系统体验的数字化突破:得物自动化评测平台的技术实践|AICon 文章整理
算法·架构·llm
VALENIAN瓦伦尼安教学设备12 小时前
转子/行星/平行轴齿轮箱综合故障模拟实验台可复现常见机械问题
大数据·数据库·人工智能·嵌入式硬件·算法
rannn_11112 小时前
【力扣hot100】哈希表专题——从两数之和到最长连续序列
java·算法·leetcode·哈希
lingran__12 小时前
C++_stack和queue和priority_queue(容器适配器)
开发语言·c++
小保CPP12 小时前
OpenCV C++基于极值区域滤波算法的场景文本检测(OCR)
c++·人工智能·opencv·算法·计算机视觉·ocr
星恒随风12 小时前
C++ 多态底层原理:静态绑定、动态绑定、虚函数表与工程实践
开发语言·c++·笔记·学习
白色冰激凌12 小时前
[SECS/GEM研究] (四)HSMS 用TCP取代串口
网络·c++·网络协议·secs/gem
来一碗刘肉面13 小时前
字符串模式匹配(朴素模式匹配算法与KMP算法)
数据结构·算法