设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
给出1个质数P,找出P最小的原根。
输入
输入1个质数P(3 <= P <= 10^9)
输出
输出P最小的原根。
输入样例
3
输出样例
2代码:
问题给出了原根的定义,对于质数p,他的欧拉函数值是p-1,还需要知道这里的阶的定义:
设m>1,gcd(a,m)=1,a^r≡1(mod m)的最小的r就是a对模m的阶。
具体怎么求,一般方法是枚举a从2开始,然后枚举r∈[2,φ(m)),如果都不满足a^r≡1(mod m),那么说明a满足,但是过于暴力,
更简单的是,设φ(m)=p1^q1*p2^q2*...*pn^qn,直接判断a^(φ(m)/pi)≠1(mod m)(i∈[1,n])恒成立即可。
#include <iostream> #include <cstdio> #define MAX 100000 using namespace std; typedef long long ll; ll p; int c,flag; ll s[MAX]; void getp(int x) { for(int i = 2;i * i <= x;i ++) { if(x % i == 0) { s[c ++] = i; while(x && x % i == 0) { x /= i; } } } if(x) s[c ++] = x; } ll pow_p(ll a,ll b) {///a^b mod p ll d = 1; while(b) { if(b % 2) d = (d * a) % p; a = (a * a) % p; b /= 2; } return d; } int main() { scanf("%lld",&p); getp(p - 1);///获取质因子 for(int i = 2;i < p;i ++) { for(int j = 0;j < c;j ++) { if(pow_p(i,(p - 1) / s[j]) == 1) { flag = 1; break; } } if(flag) flag = 0; else { printf("%d",i); break; } } }
如果觉得有帮助,点个推荐啦~