关于原根的一些知识点:
设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
定义1:设,
,使得
成立的最小的
,称为
对模
的阶,记为
。
定理1:如果模有原根,那么它一共有
个原根。
定理2:若,
,
,则
。
定理3:如果为素数,那么素数
一定存在原根,并且模
的原根的个数为
。
定理4:设是正整数,
是整数,若
模
的阶等于
,则称
为模
的一个原根。
假设一个数对于模
来说是原根,那么
的结果两两不同,且有
,那么
可以称为是模
的一个原根,归根到底就是
当且仅当指数为
的时候成立。(这里
是素数)
定理5:模有原根的充要条件:
,其中
是奇素数。
求模素数原根的方法:对
素因子分解,即
是
的标准分解式,若恒有
成立,则就是
的原根。(对于合数求原根,只需把
换成
即可)
以上内容转自http://blog.csdn.net/acdreamers/article/details/8883285
我的补充:
1.如果g为p的原根,则:g^i mod p ≠ g^j mod p (p为素数), 其中i ≠ j且i, j介於1至(p-1)之间
求原根的代码:
/*求原根模板
*/
#include
#include
#include
using namespace std;
#define LL __int64
vector
a;
LL Ext_gcd(LL a,LL b,LL &x,LL &y){
if(b==0) { x=1, y=0; return a; }
LL ret= Ext_gcd(b,a%b,y,x);
y-= a/b*x;
return ret;
}
LL Inv(LL a,int m){ //求逆元
LL d,x,y,t= (LL)m;
d= Ext_gcd(a,t,x,y);
if(d==1) return (x%t+t)%t;
return -1;
}
LL a_b_MOD_c(LL a,LL b,LL mod){
LL ret = 1;
a %= mod;
while(b){
if(b & 1) ret = ret * a % mod;
a = a * a % mod;
b >>= 1;
}
return ret;
}
bool g_test(LL g,LL p){
for(LL i=0;i
题目:
poj 1284
题意:
给出一个数n,求原根数目。
限制:
3 <= n < 65536; n为奇素数。
思路:
因为n是素数,所以模n的原根数=phi(phi(n))=phi(n-1)。
phi(i) 可以预处理出来。
/*poj 1284
题意:
给出一个数n,求原根数目。
限制:
3 <= n < 65536; n为奇素数。
思路:
因为n是素数,所以模n的原根数=phi(phi(n))=phi(n-1)。
phi(i) 可以预处理出来。
*/
#include
#include
using namespace std;
const int N=100005;
int pri[N],pcnt;
int phi[N];
void getphi(){
phi[1]=1;
for(int i=2;i