【20170919】2017暑假北京学习 day 2 - 4 BSGS算法 求𝑎 ^ 𝑥 ≡ 𝑏 (mod 𝑚) 最小整数解
一、引入
先丢个题目出来——
已知 a,b,m,求 𝑎 ^ 𝑥 ≡ 𝑏 (mod 𝑚) ( m <=10^8 ) 的最小正整数解。
1)立刻想到线性枚举 x,然后运算求解,时间复杂度O(m*logm),TLE。。。
2)枚举 x=1,2,3,……,m-2,m-1,m,m+1,m+2,..... (当x>=m+1时,所得结果在 mod m 意义下与 x=1,2,3,... 重复)
求出
s1=a^1 (mod m)
s2=a^2 (mod m)
s3=a^3 (mod m)
…
sm=a^m (mod m)
对 s[ ] 进行排序and二分查找b,得出最小解x,
时间复杂度为O(m*logm*logm),TLE。。。
还有没有更好的方法呢?
二、BSGS算法(又称“大步小步”算法,俗称“北上广深”算法)
用途:
求 𝑎 ^ 𝑥 ≡ 𝑏 (mod 𝑚) 的最小正整数解。
时间复杂度:O( sqrt(m) * logm )
空间复杂度:O( sqrt(m) )
算法思路:
依据本文 { 一、2)} 的思路,我们将s1,s2,....sm排成一个每行元素个数为 k=√m 的矩阵
a^1 a^2 a^3 … a^k
a^(k+1) a^(k+2) a^(k+3) … a^2k
… … … … …
… … … … a^(k^2)
我们发现,每一纵行的数据拥有这样的特性:
本纵行第 i 行的数据 a ^ ( i*k + 1 ),与本纵行第一横行的数据 a ^ 1 之比为 a ^ ( i*k )。
——据此,我们可以通过 第一行的某个数据 (a ^ j) 乘上 [ a^ ( i*k ) ] 推出 其下一纵行的所有数据 a ^ ( i*k + j )。
类似于本文 { 一、2)} ,
我们可以仅对 第一横行元素 进行排序【O(logn)】,即仅对a^1,a^2,....,a^k进行排序,
那么答案 b 在第一横行对应的数值是 { b / [ a^ ( i*k ) ] } ,
然后根据上一行所总结出的规律,从上至下,对每一行进行二分查找【 O( k * logk ) 】即可。
思路总结:
Step 1:计算 a^x,按照k=√m分组置入矩阵
Step 2:在 a^1 ~ a^k 中,二分查找b
Step 3:如果第i-1行找不到b,则继续在a^1~a^k中,二分查找 { b / [ a^ ( i*k ) ] } <==> 在a ^ [ ( i - 1 )*k + 1 ] ~ a ^( i*k )中寻找b
注意事项:
1. 因为在计算{ b / [ a ^ ( i*k ) ] }时用到了除法,所以在mod m的意义下应该用逆元;
2. 算法执行过程中只计算存储a^1~a^k。空间复杂度降至O( sqrt(m) )。
代码:
1 /*BSGS算法*/
2 #include<stdio.h>
3 #include<math.h>
4 #include<stdlib.h>
5
6 int a,b,m;
7 int sqrtM;
8 int *array;//存放 a^x 的数组
9
10 int QuickPow(int base,int index);
11 //快速幂函数,此处不详细写了
12 int FindinMod(int head,int tail,int goal,int mod);//==========
13 //在mod情况下二分查找的函数,下次编辑的时候补充
14 //若找到则返回目标所在下标 i,找不到则返回 0 。
15 int main()
16 {
17 scanf("%d%d%d",&a,&b,&m);
18 sqrtM=sqrt(m);
19 array=(int *)malloc(sizeof(int)*sqrtM+1);//动态申请数组
20
21 int i;
22 for(i=1;i<=sqrtM;i++)
23 array[i]=QuickPow(a,i)%m;
24
25 int seat;
26 for(i=1;i<=sqrtM;i++)
27 {
28 seat=FindinMod(1,sqrtM,b/( QuickPow(a,i*sqrtM) ));
29 if(seat)
30 {
31 printf("%d\n",(i-1)*sqrtM+seat);//输出指数x
32 break;
33 }
34 }
35 return 0;
36 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步