BSGS算法学习

嗯哼大步小步法。

一个非常暴力的想法.

注意到如果设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 }

 

posted @ 2018-02-27 11:50  大奕哥&VANE  阅读(180)  评论(0编辑  收藏  举报