原根
阶
由欧拉定理知,若
因此满足
此外还有“半阶”的概念,
在互质的条件下,阶一定存在,半阶不一定存在
性质1
证明:
假设存在
但显然有
性质2
若
证明:
对
若
这与阶的最小性矛盾,故
- 据此还有:若
,则有 .
性质3
设
性质4
设
性质3,4证明略,可以看oi-wiki。
原根
设
特别的,当
在抽象代数中,原根就是循环群的生成元。这个概念只在模 m 缩剩余系关于乘法形成的群中有「原根」这个名字,在一般的循环群中都称作「生成元」。
并非每个模 m 缩剩余系关于乘法形成的群都是循环群,存在原根就表明它同构于循环群,如果不存在原根就表明不同构。 ——引自oi-wiki
原根判定定理
设
对于
证明:必要性显然,否则不符合最小性。
充分性考虑反证,假设存在一个g,满足该条件但不是原根。
由于
但,g 不是 m 的原根,所以
原根个数
若一个数
证明:
若 m 有原根 g,由阶的性质4得:
所以若
注意到,这些
原根存在定理
一个数
证明极为复杂,因此略。
求原根
经某些dalao证明,质数
我们首先判断该数字是否有原根,然后暴力枚举判断最小原根,最后用原根个数定理中的条件找出剩下的
我们寻找n的最小原根的复杂度是
[模板] 原根
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int T,n,d,phi[maxn],p[maxn],cnt,vis[maxn];
int rt[maxn],tot,f[maxn],ans[maxn],num;
void init(){
phi[1]=1;
for(int i=2;i<=maxn-5;i++){
if(!vis[i]) p[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt&&i*p[j]<=maxn-5;j++){
vis[i*p[j]]=1;
if(i%p[j]==0){
phi[i*p[j]]=phi[i]*p[j];
break;
} else phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
rt[2]=rt[4]=1;
for(int i=2;i<=cnt;i++){
for(long long j=p[i];j<=maxn-5;j*=p[i]) rt[j]=1;//小心炸int
for(long long j=2*p[i];j<=maxn-5;j*=p[i]) rt[j]=1;
}
}
int gcd(int x,int y){
if(y==0) return x;
return gcd(y,x%y);
}
int qpow(int x,int y,int p){
int res=1;
while(y){
if(y&1) res=1ll*res*x%p;
x=1ll*x*x%p;
y>>=1;
}
return res;
}
void div(int n){
tot=0;
for(int i=2;i<=n/i;i++){
if(n%i==0){
f[++tot]=i;
while(n%i==0) n/=i;
}
}
if(n>1) f[++tot]=n;
}
bool check(int x,int n){
if(gcd(x,n)!=1) return 0;
for(int i=1;i<=tot;i++){
if(qpow(x,phi[n]/f[i],n)==1) return 0;
}
return 1;
}
int findrt(int n){
for(int i=1;i<n;i++){
if(check(i,n)) return i;
}
return 0;
}
void getrt(int n,int x){
int y=1; num=0;
for(int i=1;i<=phi[n];i++){
y=1ll*y*x%n;
if(gcd(i,phi[n])==1) ans[++num]=y;
}
}
int main(){
init();
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&d);
if(rt[n]){
div(phi[n]);
int mn=findrt(n);
getrt(n,mn);
sort(ans+1,ans+num+1);
printf("%d\n",num);
for(int i=d;i<=num;i+=d) printf("%d ",ans[i]);
printf("\n");
} else printf("0\n\n");
}
return 0;
}
指标
指标,又称离散对数,就是在模意义下进行的对数运算。设
则称
性质和普通对数类似
-
若
,则 -
-
例
bzoj 1420. Discrete Root
它问的是
如果你对算法比较熟悉,就会想到BSGS算法:求
那么我们试图把在底数上的未知数转化到指数上。
已知
由阶的性质1,对于
那么方程转化为
我们就可以用 BSGS 求出 f(x) 进而求出
还有一种方法是用指标转化,直接就出来了(但笔者在写这题的时候还没学指标
bzoj 2219. 数论之神
跟上一题的区别在于这个模数不一定有原根,然后我们就需要一系列的分解质因数和化为同余方程组。需要一个巨大的分讨来求解因数个数。
我刚把那一坨latex打完,直接退出,直接完蛋。。全**丢了,气死了
本文作者:YYYmoon
本文链接:https://www.cnblogs.com/YYYmoon/p/18718153
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步