1. 程式人生 > >階&原根

階&原根

要求 方法 alt 質因數 src spa 測試 col ==

技術分享圖片

技術分享圖片

求階的方法:

根據性質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 }

階&原根