「原根」与「阶」
2019-09-26 本文已影响0人
雨落八千里

阶
定义:
设,那么使得
成立的最小正整数
就称为
模
的阶.记作
并且
总是可以整除
即
是
由定义,是满足
的最小正指数,而
,故有
因此
原根
定义:
一个数是一个
是原根,则
的结果两两不相同,其中,
如果与
是互质的整数且
,那么当
的阶
时,称
为模
的原根。
就是在多个都可以满足
其中
是使得
模
等于
的最小正整数就称
但是其中只有和
是模
的原根.
质数
原根求法:
给出一个质数
将通过唯一分解定理可以得到:
其中
都是质数
然后枚举,若
则是模
的一个原根
原根性质:
- 所有的质数
都可以找到原根,且个数是
![]()
- 不是所有的整数都有原根
- 若模
可以找到原根,那么
一定可以表示成
这些形式的一种,其中
是奇质数
- 若模
可以找到原根,那么它能找到原根的个数一定是
![]()
- 模
的最小原根大小是
的。所以有些东西你枚举就够了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=1e5+10;
int p[M],cnt;
void ol(ll n)//将φ(m)唯一定理分解
{
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
p[cnt++]=i;
}
while(n%i==0)
{
n/=i;
}
}
if(n>1)
{
p[cnt++]=n;
}
return ;
}
ll qpow(ll a,ll n,ll mod)
{
ll ans=1;
ll base=a;
while(n)
{
if(n&1)
{
ans=ans*base%mod;
}
base=base*base%mod;
n>>=1;
}
return ans%mod;
}
ll query(ll n)
{
if(n==2||n==4)
{
return n-1;
}
cnt=0,ol(n-1);
for(int i=2;i<n;i++)//从小到大遍历a
{
int flag=1;
for(int j=0;j<cnt;j++)
{
if(qpow(i,(n-1)/p[j],n)==1)//根据原根求法
{
flag=0;
break;
}
}
if(flag==1)//输出最小的原根
{
return i;
}
}
}
int main( )
{
ll n;
while(~scanf("%lld",&n))
{
printf("%lld\n",query(n));
}
return 0;
}