BSGS算法学习

本文介绍了一种解决特定数学问题的方法——大步小步法。该方法通过预处理和哈希表来快速求解指数方程。具体地,通过设定C为P的平方根的上界,将任意数表示为a1*C+b1形式,从而加速求解过程。复杂度为O(√P),适用于如POJ2417等题目。
摘要由CSDN通过智能技术生成

嗯哼大步小步法。

一个非常暴力的想法.

注意到如果设C = ⌈√P⌉,那么任何一个数都可以写

成a1 * C + b1的形式,其中a1, b1 都< C.

那么预处理出A^i*C的值.然后在询问时枚举b1.

A^a1*C-b1 = B,A^a1*C = B * A^b1.

把A^b1乘一下,再去hash表里查找是否有对应的值即可.

复杂度为O(√P)

//POJ 2417

 1 #include<cstdlib>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<iostream>
 6 #include<map>
 7 #include<cmath>
 8 using namespace std;
 9 typedef long long ll;
10 map<ll,int>mmp;
11 int qmod(ll a,ll b,ll p)
12 {
13     ll ans=1;
14     while(b)
15     {
16         if(b&1)ans=ans*a%p;
17         a=a*a%p;b>>=1;
18     }
19     return ans;
20 }
21 int main()
22 {
23     ll p,a,b;
24     while(~scanf("%lld%lld%lld",&p,&a,&b))
25     {
26         mmp.clear();
27         if(a%p==0)
28         {
29             puts("no solution");
30             continue;
31         }
32         bool flag=0;
33         ll ans=0;
34         int c=ceil(sqrt(p));
35         for(int i=0;i<=c;++i)
36         {
37             if(i==0)
38             {
39                 ans=b%p;mmp[ans]=i;continue;
40             }
41             ans=ans*a%p;
42             mmp[ans]=i;
43         }
44         ll tmp=qmod(a,c,p);ans=1;
45         for(int i=1;i<=c;++i)
46         {
47             ans=ans*tmp%p;
48             if(mmp[ans])
49             {
50                 tmp=i*c-mmp[ans];
51                 printf("%d\n",(tmp%p+p)%p);
52                 flag=1;
53                 break;
54             }
55         }
56         if(!flag)puts("no solution");
57     }
58     return 0;
59 }

 

转载于:https://www.cnblogs.com/nbwzyzngyl/p/8478115.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值