原根学习笔记
原根学习笔记
原根
这是一个又臭又长的内容。
拉格朗日定理:设
为素数,对于模 意义下的整系数多项式 的同余方程
在模 意义下至多有 个不同解。
证明:使用归纳法,对于
若命题对于
从而
所以定理对
阶:由欧拉定理可知,对
,若 ,则 因此满足同余式
的最小正整数 存在,这个 称作 模 的阶,记作 。 原根:设
。若 ,且 ,则称 为模 的原根。
关于阶有一个较为显然的性质:
若
,则 。
证明:对
若
这与
关于阶还有两个重要的性质:
性质
:设 ,则 的充要条件是
。
证明:必要性:有
由前面所述的性质,有
有由于
所以
充分性:由
故
对称地,可得
所以
另一方面,有
故
综合即可得到
性质
:设 ,则
证明:注意到
另一方面,由
所以
综合可得
接下来讨论什么样的
首先,对于
定理
:对于奇素数 , 存在原根。
证明:先证明一个引理:
引理:设
与 是与 互素的两个整数,则存在 使得 。 证明:记
,设它们的标准分解为(只要求 ) 令
为所有 的 的乘积, 为所有 的 的乘积。记 ,则 。 由性质
, ,则由性质 , ,取 即可。
对
这表明
的根。有拉格朗日定理可知,
定理
:对于奇素数 , , 有原根。
证明:先证明一个引理。
引理:存在模
的原根 ,使得 。 证明:事实上,仍取模
的原根 ,若 不满足条件,我们认定 满足条件。易知 也是模 的原根。 于是有
接着,我们证明若
首先证明下面的结论:对于任意
不难发现当
结合
所以命题对
其次,记
而由
所以可设
结合
从而
定理
:对于奇素数 , , 有原根。
证明:设
在
由欧拉定理,
而
利用
结合
定理
:对于 ,则对于任意 ,都有 ,即模 的原根不存在。
证明:对于
若
当
所以
上述定理阐述了原根的充要条件,即除了
如果一个数有原根,可以先求出其最小原根。事实上,
同时,只要满足如上条件的
假如找到了一个原根
指标
对于
求解的方法也很简单,用
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
int T,n,d,tot,cnt,sum;
int p[N],phi[N],fc[N];
ll ans[N];
bool rt[N],vis[N];
void Euler(int x){
phi[1]=1;
for(int i=2;i<=x;i++){
if(!vis[i]){
p[++tot]=i;
phi[i]=i-1;
}
for(int j=1;p[j]<=x/i;j++){
vis[i*p[j]]=true;
if(i%p[j]==0){
phi[i*p[j]]=phi[i]*p[j];
break;
}
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
rt[1]=rt[2]=rt[4]=true;
for(int i=2;i<=tot;i++){
for(int j=1;j<=x/p[i];j*=p[i])rt[j*p[i]]=true;
for(int j=2;j<=x/p[i];j*=p[i])rt[j*p[i]]=true;
}
return ;
}
int Gcd(int a,int b){
return b==0?a:Gcd(b,a%b);
}
ll QuickPow(ll a,int b,int p){
ll res=1;
while(b>0){
if((b&1)==1)res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
}
void Fac(int x){
cnt=0;
for(int i=1;p[i]<=x/p[i];i++){
if(p[i]>x)break ;
if(x%p[i]==0){
fc[++cnt]=p[i];
while(x%p[i]==0)x/=p[i];
}
}
if(x>1)fc[++cnt]=x;
return ;
}
bool Check(int x,int p){
if(QuickPow(x,phi[p],p)!=1)return false;
for(int i=1;i<=cnt;i++){
if(QuickPow(x,phi[p]/fc[i],p)==1)return false;
}
return true;
}//检验是否是原根
int FindRt(int x){
for(int i=1;i<x;i++){
if(Check(i,x))return i;
}
return 0;
}//找最小原根
void GetRt(int x,int p){
ll res=1;
sum=0;
for(int i=1;i<=phi[p];i++){
res=res*x%p;
if(Gcd(i,phi[p])==1)ans[++sum]=res;
}
return ;
}//处理所有原根
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>T;
Euler(N-5);//预处理质数、phi、有无原根
while(T--){
cin>>n>>d;
if(rt[n]){
Fac(phi[n]);//预处理质因数
GetRt(FindRt(n),n);//找最小原根后找所有原根
sort(ans+1,ans+sum+1);
cout<<sum<<"\n";
for(int i=1;i<=sum/d;i++)cout<<ans[i*d]<<" ";
cout<<"\n";
}else cout<<"0\n\n";//直接判断没有原根
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具