阶&原根

求阶的方法:

根据性质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 }

猜你喜欢

转载自www.cnblogs.com/fzl194/p/9037947.html