- gf24240 的博客
《梦溪笔谈·C++》卷二十六:原根判断
- 2025-6-20 23:24:15 @
背景
28 号就要考五级了
来源:洛谷P11961 [GESP202503 五级] 原根判断
P11961 [GESP202503 五级] 原根判断
题目描述
小 A 知道,对于质数 而言, 的原根 是满足以下条件的正整数:
- ;
- ;
- 对于任意 均有 。
其中 表示 除以 的余数。
小 A 现在有一个整数 ,请你帮他判断 是不是 的原根。
输入格式
第一行,一个正整数 ,表示测试数据组数。
每组测试数据包含一行,两个正整数 。
输出格式
对于每组测试数据,输出一行,如果 是 的原根则输出 Yes
,否则输出 No
。
输入输出样例 #1
输入 #1
3
3 998244353
5 998244353
7 998244353
输出 #1
Yes
Yes
No
说明/提示
数据范围
对于 的测试点,保证 。
对于所有测试点,保证 ,,, 为质数。
题解
其实写完才发现,好像考的知识也不是很难,就是快速幂和质因数分解。如果没了解过,赶紧去请教一下D老师。
先一条一条地看原根的判断条件:
- ;
- ;
- 对于任意 均有 。
这一条并不难,数据范围已经保证了这一点。
只要会快速幂,这一点也不难。这要根据描述来判断就好了。
对于任意 均有
难点就在这了。首先想到的就是 for
循环,遍历 1
到 p-2
,如果检查到一个 ,就直接 return false;
就好了。但是数据很大, 的算法肯定会超时。看到数据很大,一定会想到 的算法。(好像我们已经学了的就是贪心、数学和二分了)二分应该不行,因为 的分布行不是有序的。 剩下就是贪心和数学。
反过来想,要保证 中均有 ,其实只需要在 中找到一个 ,使 就好了。那如何找呢?
,那么 等于多少呢?很显然也是 。那么 , , 等都为 。即 。根据第二条条件,可以发现, 。根据前面的 ,那么 一定是这个 的倍数。而且可以证明,如果 不是 的倍数如图1,是不成立的:
这样就变简单了,只需要判断 的因子中有没有一个 能使 。这很容易想到质因数分解。只需要把 进行质因数分解,在逐个判断就好了。时间复杂度: 。代码:
VIP内容