博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

原根 学习笔记

主要参考这里:
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]序列统计

posted @ 2018-11-30 15:31  SovietPower  阅读(1668)  评论(0编辑  收藏  举报