问题:给定三个数a,b,p,保证a,p互质,求解
a
x
≡
b
(
m
o
d
p
)
a^x\equiv b \ (mod \ p)
ax≡b (mod p)
最小正整数
x
x
x
1
<
=
a
,
b
,
p
<
=
1
0
9
\ \ \ 1<=a,b,p<=10^9
1<=a,b,p<=109
BSGS(拔山盖世 大步小步算法)
根据欧拉定理:
a
φ
(
n
)
≡
1
a^{\varphi (n)}\equiv 1
aφ(n)≡1
(
m
o
d
(mod
(mod
n
)
n)
n)
可以看出指数的同余的循环节
直接暴力时间复杂度
O
(
φ
(
n
)
)
O(\varphi (n))
O(φ(n))
考虑优化
令
x
=
p
′
q
−
r
x=p'q-r
x=p′q−r (同余常见搞法,设
a
=
p
b
+
r
a=pb+r
a=pb+r 加减一样)
则
A
p
′
q
≡
b
∗
A
r
A^{p'q}\equiv b*A^r
Ap′q≡b∗Ar
(
m
o
d
(mod
(mod
n
)
n)
n)
首先在
O
(
p
′
)
O(p')
O(p′)内求出
a
a
a至
a
p
′
−
1
a^{p'-1}
ap′−1每一个的值(
a
,
a
2
,
a
3
.
.
.
a,a^2,a^3...
a,a2,a3...)
并把这些值存入哈希表
然后枚举
q
q
q,每次从哈希表中查询是否有满足原式的值
时间复杂度
O
(
m
a
x
(
p
′
,
φ
(
p
)
/
p
′
)
)
O(max(p',\varphi (p)/p'))
O(max(p′,φ(p)/p′))
显然最优是令
p
′
=
φ
(
p
)
p'=\sqrt{\varphi (p)}
p′=φ(p)
总的时间复杂度
O
(
φ
(
p
)
)
O(\sqrt{\varphi (p)})
O(φ(p))
That’s all.
C o d e Code Code
(
p
p
p为质数,
a
,
p
a,p
a,p互质还可以求
φ
(
p
)
\varphi (p)
φ(p))
模板题:SDOI2011 计算器
TJOI2007 可爱的质数
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int Mod=1e5+7;
const int MAXN=1<<20;
struct w{
int to,nx,s;
w(){s=-1;}
}Hash[MAXN+10];
int a[Mod+10],tot=0;
inline void add(int,int,int,int);
void Insert(int);
int Query(int);
void BSGS(int,int,int);
signed main(){
//freopen ("std.in","r",stdin);
//freopen ("std.out","w",stdout);
int p,b,n;
scanf("%lld%lld%lld",&p,&b,&n);
BSGS(p,n,b);
return 0;
}
inline void add(int x,int i,int val,int s){Hash[i].to=val,Hash[i].s=s,Hash[i].nx=a[x],a[x]=i;}
void Insert(int val,int s){
int x=val%Mod;
add(x,++tot,val,s);
}
int Query(int val){
int x=a[val%Mod];
while (Hash[x].to!=val && Hash[x].to) x=Hash[x].nx;
return Hash[x].s;
}
void BSGS(int p,int n,int a){
int m=sqrt(p)+1,t=1,tt;
for (register int i=0;i<m;++i){
Insert((t*n)%p,i);
t=(t*a)%p;
}
tt=t;
for (register int i=1;i<=m;++i){
int k=Query(t);
t=(t*tt)%p;
if (k==-1) continue;
printf("%lld\n",i*m-k);
return;
}
printf("no solution\n");
}