益智遊戲網開發之路六(網址yzyx.info)
阿新 • • 發佈:2022-05-15
原根
定義:如果 \(g\;(mod\;m)\) 的階為 \(\phi(m)\) 則 \(g\) 為 \(m\) 的原根
\(g^0,g^1,...g^{\phi(m)-1}\) 構成了模 \(m\) 的簡化剩餘系 (即 \([1,m-1]\) 中與 \(m\) 互質的數可以被原根 \(g\) 的階表示出來)
只有 \(1, 2, 4, p^a,2*p^a\;(p\;為奇素數,\;a\;為正整數)\) 存在原根
對於素數 \(p\), 有如下性質
-
\(p\) 的原根有 \(\phi(p-1)\) 個
-
\(p\) 的原根大致隨機分佈在 2 ~ p - 1 中
-
由 1,2 兩條性質,\(p\)
-
\(p\) 的原根不一定是 \(p^2\) 的原根,\(p^2\) 的原根一定是更高次的原根
原根 - 題目 - Daimayuan Online Judge
#include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <cmath> using namespace std; typedef long long ll; int divisor[100]; ll qmi(ll a, ll b, ll p) { ll ans = 1; while(b) { if (b & 1) ans = ans * a % p; b >>= 1; a = a * a % p; } return ans % p; } int solve(int p) { int t = 0; int now = p - 1; for (int i = 2; i <= now / i; i++) { if (now % i) continue; divisor[++t] = i; while(now % i == 0) now /= i; } if (now > 1) divisor[++t] = now; for (int g = 1; g < p; g++) { bool flag = true; for (int i = 1; i <= t; i++) { int d = divisor[i]; if (qmi(g, (p - 1) / d, p) == 1) //如果 phi(p-1) 能除以一個因子,那這個 g 就不是原根 { flag = false; break; } } if (flag) return g; } } int main() { int T; scanf("%d\n", &T); while(T--) { int p; scanf("%d", &p); printf("%d\n", solve(p)); } return 0; }