原根 学习笔记

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

定义:

定义(a)(m)的阶为,使得(a^tequiv1 (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}} otequiv 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^tequiv a (mod p)(1leq tleq p-1)),则相应的指数(t)被称为(g)为底的(a)(p)的指标。若(p,g)已知,则记指标为(I(a)),即(I(a)=t)

那么有指标法则

[egin{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
",Find_root(read()));
	return 0;
}

另一道例题:BZOJ.3992.[SDOI2015]序列统计

原文地址:https://www.cnblogs.com/SovietPower/p/10044472.html