离散对数介绍

文章介绍了欧拉函数的概念,包括模运算中的阶和原根定义,并详细阐述了如何寻找原根。接着讨论了离散对数的性质及其作用,即如何将模m乘法转换为模φ(m)加法。最后提供了一段代码示例,用于寻找原根和计算离散对数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前置知识

欧拉函数 ϕ ( n ) \phi(n) ϕ(n)

欧拉函数简介

g g g n n n互质,则令 g x % n = 1 g^x\%n=1 gx%n=1的最小正整数 x x x称为 g g g n n n的阶。

原根

对于互质的两个正整数 g g g n n n,如果 g g g n n n的阶为 ϕ ( n ) \phi(n) ϕ(n),则称 g g g n n n的原根。

求原根

一般的原根都比较小,暴力枚举即可。


离散对数

g g g m m m的原根,则当

g k ≡ x ( m o d m ) g^{k}\equiv x\pmod m gkx(modm)

时,有

Ind g x ≡ k ( m o d ϕ ( m ) ) \text{Ind}_gx\equiv k\pmod{\phi(m)} Indgxk(modϕ(m))

而且能保证 ∀ x ∈ [ 1 , m − 1 ] \forall x\in[1,m-1] x[1,m1],都存在 k ∈ [ 1 , m − 1 ] k\in[1,m-1] k[1,m1]使得 g k = x g^k=x gk=x

证明

∃ x ∈ [ 1 , m − 1 ] \exist x\in[1,m-1] x[1,m1],不存在 k k k使得 g k = x g^k=x gk=x

∃ y ∈ [ 1 , m − 1 ] \exist y\in[1,m-1] y[1,m1],存在至少两个 k ∈ [ 1 , m − 1 ] k\in[1,m-1] k[1,m1]使得 g k = y g^k=y gk=y

设满足条件的 k k k中不同的两个为 k 1 k_1 k1 k 2 k_2 k2 k 1 < k 2 k_1<k_2 k1<k2

g k 1 ≡ g k 2 ( m o d m ) g^{k_1}\equiv g^{k_2}\pmod m gk1gk2(modm)

g k 2 − k 1 ≡ 1 ( m o d m ) g^{k_2-k_1}\equiv 1\pmod m gk2k11(modm)

所以 g g g不为 m m m的原根,矛盾

由此即可得证

离散对数的性质

离散对数的性质与对数函数的性质相似

Ind g ( x y ) = Ind g ( x ) + Ind g ( y ) ( m o d ϕ ( m ) ) \text{Ind}_g(xy)=\text{Ind}_g(x)+\text{Ind}_g(y)\pmod{\phi(m)} Indg(xy)=Indg(x)+Indg(y)(modϕ(m))

Ind g ( x y ) = y ⋅ Ind g ( x ) ( m o d ϕ ( m ) ) \text{Ind}_g(x^y)=y\cdot \text{Ind}_g(x)\pmod{\phi(m)} Indg(xy)=yIndg(x)(modϕ(m))

离散对数的作用

可以将模 m m m意义下的乘法转换为模 ϕ ( m ) \phi(m) ϕ(m)意义下的加法,从而更方便地解决问题。

code

int find(int e){
	for(int i=2;i<=e;i++){
		for(int j=1,l=i;j<=e;j++,l=l*i%e){
			if(l==1){
				if(j==e-1) return i;
				break;
			}
		}
	}
}//找原根
void init(){
	int gt=find(m);
	for(int i=0,l=1;i<m-1;i++){
		ind[l]=i;
		l=l*gt%m;
	}
}//求离散对数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值