原根 學習筆記


主要參考這里:
http://www.cnblogs.com/autsky-jadek/p/7496178.html
https://blog.csdn.net/a27038/article/details/77203892

定義:

定義\(a\)\(m\)的階為,使得\(a^t\equiv1\ (mod\ m)\)成立的最小正整數\(t\)\(a,m\)互質)。用\(\delta_m(a)\)表示。
\(a,m\)互質且\(\varphi(m)=\delta_m(a)\)時,則稱\(a\)為模\(m\)的一個原根。

\(m\)存在原根的充要條件:\(m=2,4,p^a,2p^a\),其中\(p\)是奇素數。
若模一個數\(p\)存在原根,那么其原根個數為\(\varphi(\varphi(p))\)

求模\(P\)的原根:

\(P\)是質數,將\(P-1\)質因數分解,即令\(P-1=\prod_{i=1}^kp_i^{a_i}\)
若對於\(i=1,2,...,k\),都有$$g^{\frac{P-1}{p_i}}\not\equiv 1\ (mod\ P)$$

那么\(g\)就是\(P\)的一個原根(\(g\)可以直接枚舉,通常原根不會太大)。

\(P\)是合數,將\(P-1\)換成\(\varphi(P)\)即可。

性質:

\(g\)是模\(p\)的一個原根,則\(g,g^2,...,g^{\varphi(p)}\)在模\(p\)意義下兩兩不同,且恰好是小於\(p\)且與\(p\)互質的\(\varphi(p)\)個正整數的一個排列。

下面考慮\(p\)是質數的情況(合數一樣嗎我不太清楚啊...)

\(g^t\equiv a\ (mod\ p)(1\leq t\leq p-1)\),則相應的指數\(t\)被稱為\(g\)為底的\(a\)\(p\)的指標。若\(p,g\)已知,則記指標為\(I(a)\),即\(I(a)=t\)

那么有指標法則

\[\begin{aligned}I(ab)&\equiv I(a)+I(b)\ (mod\ p-1)\ [乘積法則]\\I(a^k)&\equiv kI(a)\ (mod\ p-1)\ [冪法則]\end{aligned} \]

這樣就可以將乘法化為加法,與連續數學中的對數很相似,因此指標也叫做離散對數。

下面是一道求原根的模板題:
51Nod.1135.[模板]原根

//46ms	1,880KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e6+5;

inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-'0',c=gc());
	return now;
}
inline int FP(int x,int k,int mod)
{
	int t=1;
	for(; k; k>>=1,x=1ll*x*x%mod)
		if(k&1) t=1ll*t*x%mod;
	return t;
}
int Find_root(int P)
{
	static int p[N];
	int cnt=0,x=P-1;
	for(int i=2; i*i<=x; ++i)
		if(!(x%i))
		{
			p[++cnt]=i;
			while(!(x%i)) x/=i;
		}
	if(x!=1) p[++cnt]=x;
	for(int x=2; ; ++x)
	{
		bool ok=1;
		for(int i=1; i<=cnt; ++i) if(FP(x,(P-1)/p[i],P)==1) {ok=0; break;}
		if(ok) return x;
	}
	return -1;
}

int main()
{
	printf("%d\n",Find_root(read()));
	return 0;
}

另一道例題:BZOJ.3992.[SDOI2015]序列統計


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM