阶&原根
求阶的方法:
根据性质2,直接对ϕ(m)求出因子即可,从小到大依次判断是不是符合ad = 1(mod m)(d是ϕ(m)的因子)
求最小的原根的方法:
根据性质8,对ϕ(m)求出素因子,从1开始不断测试即可,因为最小的原根很容易暴力得到。
求原根代码:(下面代码是求素数p的原根,如果不是素数,需要求出p的欧拉函数值,由于是素数,所以欧拉函数值为p-1)
1 ll pow(ll a, ll b, ll m) 2 { 3 a %= m; 4 ll ans = 1; 5 while(b) 6 { 7 if(b & 1)ans = ans * a % m; 8 a = a * a % m; 9 b /= 2; 10 } 11 return ans % m; 12 } 13 int tot;//素因子个数 14 int a[100005]; 15 void get_fact(ll n)//质因数分解n 16 { 17 for(ll i = 2; i * i <= n; i++) 18 { 19 if(n % i == 0) 20 { 21 a[tot++] = i; 22 while(n % i == 0)n /= i; 23 } 24 } 25 if(n != 1)a[tot++] = n; 26 } 27 bool g_test(ll g, ll p)//测试g是不是p的原根 此处p是素数 欧拉函数值为p - 1 28 { 29 for(ll i = 0; i < tot; i++) 30 { 31 if(pow(g, (p - 1) / a[i], p) == 1)return false; 32 } 33 return true; 34 } 35 int proot(ll p) 36 //求解p最小原根,本题p为素数 37 //返回最小的原根 38 { 39 get_fact(p - 1);//素数的欧拉函数值为p - 1 40 int g = 1; 41 while(1) 42 { 43 if(g_test(g, p))return g; 44 g++; 45 } 46 }
越努力,越幸运