码迷,mamicode.com
首页 > 编程语言 > 详细

BSGS算法

时间:2018-04-12 20:56:56      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:最快   检查   复杂   没有   gcd   否则   计算器   取值   算法   

BSGS算法

我是看着\(ppl\)的博客学的,您可以先访问\(ppl\)的博客

Part1 BSGS算法

求解关于\(x\)的方程
\[y^x=z(mod\ p)\]

其中\((y,p)=1\)
做法并不难,我们把\(x\)写成一个\(am-b\)的形式
那么,原式变成了
\(y^{am}=zy^b(mod\ p)\)
我们求出所有\(b\)可能的取值(0~m-1),并且计算右边的值
同时用哈希或者\(map\)之类的东西存起来,方便查询
对于左边,我们可以枚举所有可能的\(m\),然后直接查右边的值有没有相等的即可
复杂度是\(O(max(m,p/m))\)
不难证明\(m=\sqrt(p)\)时复杂度最优

所以\(bsgs\)算法的复杂度是\(O(\sqrt(p))\)

模板题:\(SDOI2011\) 计算器

关键代码:

int m=sqrt(p)+1;Hash.Clear();
for(RG int i=0,t=z;i<m;++i,t=1ll*t*y%p)Hash.Insert(t,i);
for(RG int i=1,tt=fpow(y,m,p),t=tt;i<=m+1;++i,t=1ll*t*tt%p)
{
    int k=Hash.Query(t);if(k==-1)continue;
    printf("%d\n",i*m-k);return;
}

使用\(map\)会多个\(log\),在洛谷上我写的\(Hash\)目前是跑得最快的。。。

Part2 拓展BSGS

假设\(gcd(y,p)\neq 1\)怎么办?
\(d=gcd(y,p)\)
将方程改写成等式形式
\[y^x+kp=z\]
发现此时的\(z\)必须要是\(d\)的倍数,否则无解。
因此,除掉\(d\)
\[\frac{y}{d}y^{x-1}+k\frac{p}{d}=\frac{z}{d}\]
这样前面的\(y/d\)就是一个系数了,
不断检查\(gcd(\frac{z}{d},y)\),一直除到互质为止
此时的形式就变成了
\[\frac{y^k}{d}y^{x-k}=\frac{z}{d}(mod\ \frac{p}{d})\]
这样子\(bsgs\)求解之后在还原回去就行了。

BSGS算法

标签:最快   检查   复杂   没有   gcd   否则   计算器   取值   算法   

原文地址:https://www.cnblogs.com/cjyyb/p/8810050.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!