原根:
定義
設m是正整數,a是整數,若a mod m 的階等於,則稱a爲模m的一個原根(表示m的歐拉函數)
當且僅當指數爲P - 1的時候,成立,則質數P的原根即爲g
求解方法:1.將p-1進行質因數分解
2.枚舉i,並判斷對於每個i是否都有,第一個符合i的即是P 的最小原根
對於合數,只要將2中的P-1替換成
對於等價於,可使用擴展歐幾里得求解x
性質
- 若m爲原根,則恰好有個在模m下的不同原根
求原根g的模板:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+5;
LL p, primes[maxn], cnt;
bool vis[maxn];
LL fp(LL x, LL a){
LL res = 1;
for(x %= p; a; a >>= 1, x = x*x%p)
if(a & 1) res = res * x % p;
return res;
}
void get_prime(int x){ //篩出x以內的素數
for(int i = 2; i <= x; i++){
if(!vis[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt; j++){
if(i * primes[j] > x) break;
vis[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
bool check(LL x){ //檢查x是否是p的原根
LL t = sqrt(x) + 10;
for(int i = 1; i < prime[i] <= t; i++)
if((p-1) % prime[i] == 0 && fp(x, (p-1)/prime[i]) % p == 1)
return 0;
return 1;
}
int main()
{
scanf("%lld", &p); //求模p的原根
get_prime();
for(int i = 1; i <= maxn; i++){
if(check(i)){
printf("%d\n", i); //輸出的第一個數即爲最小原根
return 0;
}
}
}
指標:
原根的作用就是爲了計算指標 (指標的表示符號)。
滿足
最常見的應用:解模高次方程