BSGS算法总结

\(BSGS\)算法(Baby Step Giant Step),即大步小步算法,用于解决这样一个问题:

求\(y^x\equiv z\ (mod\ p)\)的最小正整数解。

前提条件是\((y,p)=1\)。

我们选定一个大步长\(m=\sqrt p + 1\),设\(x=am+b\),那么显然有\(a,b\in[0,m)\)。这样就有\(y^{am+b}\equiv z\ (mod\ p)\),就有\((y^m)^a=z*y^{-b}\ (mod\ p)\)。

但是这个逆元看起来很不爽,所以我们重新设\(x=am-b\),那么就有\((y^m)^a\equiv z*y^b\ (mod\ p)\)。这时候是\(a\in[1,m],b\in[0.m)\)。

具体实现方法:

分别计算出\(z*y^0,z*y^1...z*y^{m-1}\)。把算出来的这些东西放到一个表里面,这里用\(map\)和\(hash\)都是可以的。(显然\(hash\)跑得比\(map\)快到不知道哪里去了)

然后对于\(i\in[1,m]\)计算\((y^m)^i\),查一下表看这个数是不是已经被算出来了。

能算出来就能直接输出解了。

[SDOI2011]计算器

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
map<int,int>M;
int fastpow(int a,int b,int mod)
{
int res=1;
while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
return res;
}
int main()
{
int T=gi(),K=gi();
while (T--)
{
int y=gi(),z=gi(),p=gi();
if (K==1) printf("%d\n",fastpow(y,z,p));
if (K==2)
{
if (y%p==0&&z%p) puts("Orz, I cannot find x!");
else printf("%lld\n",1ll*fastpow(y,p-2,p)*z%p);
}
if (K==3)
{
if (y%p==0) {puts("Orz, I cannot find x!");continue;}
y%=p;z%=p;
int m=sqrt(p)+1,fg=0;M.clear();
for (int i=0,t=z;i<=m;++i,t=1ll*t*y%p) M[t]=i;
for (int i=1,tt=fastpow(y,m,p),t=tt;i<=m;++i,t=1ll*t*tt%p)
if (M.count(t)) {printf("%d\n",i*m-M[t]);fg=1;break;}
if (!fg) puts("Orz, I cannot find x!");
}
}
return 0;
}

扩展BSGS

如果\((y,p)\neq 1?\)

考虑\(y*y^{x-1}+k*p=z\)(注意这里是等号不是同余)

根据扩展欧几里得的那套理论,当\(z\)不是\((y,p)\)的因数的时候就会无解。

否则设\(d=(y,p)\),那么就会有\(\frac yd y^{x-1}+k*\frac pd=\frac zd\)。

不断递归下去,直至\(d=1\)。接下来就可以套用普通的\(BSGS\)了。

Spoj3105 Mod

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
int y,z,p,ans;map<int,int>M;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int fastpow(int a,int b,int mod)
{
int res=1;
while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
return res;
}
int EX_BSGS()
{
int cnt=0,sum=1;
for (int d=gcd(y,p);d!=1;d=gcd(y,p))
{
if (z%d) return -1;
++cnt,z/=d,p/=d,sum=1ll*sum*y/d%p;
if (z==sum) return cnt;
}
int m=sqrt(p)+1;M.clear();
for (int i=0,t=z;i<=m;++i,t=1ll*t*y%p) M[t]=i;
for (int i=1,tt=fastpow(y,m,p),t=1ll*sum*tt%p;i<=m;++i,t=1ll*t*tt%p)
if (M.count(t)) return i*m+cnt-M[t];
return -1;
}
int main()
{
while (233)
{
y=gi();p=gi();z=gi();
if (y+z+p==0) break;
y%=p;z%=p;ans=EX_BSGS();
if (ans==-1) puts("No Solution");
else printf("%d\n",ans);
}
return 0;
}

BSGS算法总结的更多相关文章

  1. 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法

    BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...

  2. bzoj2242: [SDOI2011]计算器 && BSGS 算法

    BSGS算法 给定y.z.p,计算满足yx mod p=z的最小非负整数x.p为质数(没法写数学公式,以下内容用心去感受吧) 设 x = i*m + j. 则 y^(j)≡z∗y^(-i*m)) (m ...

  3. [BSGS算法]纯水斐波那契数列

    学弟在OJ上加了道"非水斐波那契数列",求斐波那契第n项对1,000,000,007取模的值,n<=10^15,随便水过后我决定加一道升级版,说是升级版,其实也没什么变化,只 ...

  4. BSGS算法

    BSGS算法 我是看着\(ppl\)的博客学的,您可以先访问\(ppl\)的博客 Part1 BSGS算法 求解关于\(x\)的方程 \[y^x=z(mod\ p)\] 其中\((y,p)=1\) 做 ...

  5. BSGS算法及扩展

    BSGS算法 \(Baby Step Giant Step\)算法,即大步小步算法,缩写为\(BSGS\) 拔山盖世算法 它是用来解决这样一类问题 \(y^x = z (mod\ p)\),给定\(y ...

  6. uva11916 bsgs算法逆元模板,求逆元,组合计数

    其实思维难度不是很大,但是各种处理很麻烦,公式推导到最后就是一个bsgs算法解方程 /* 要给M行N列的网格染色,其中有B个不用染色,其他每个格子涂一种颜色,同一列上下两个格子不能染相同的颜色 涂色方 ...

  7. BSGS算法及其扩展

    bsgs算法: 我们在逆元里曾经讲到过如何用殴几里得求一个同余方程的整数解.而\(bsgs\)就是用来求一个指数同余方程的最小整数解的:也就是对于\(a^x\equiv b \mod p\) 我们可以 ...

  8. BSGS算法学习笔记

    从这里开始 离散对数和BSGS算法 扩展BSGS算法 离散对数和BSGS算法 设$x$是最小的非负整数使得$a^{x}\equiv b\ \ \ \pmod{m}$,则$x$是$b$以$a$为底的离散 ...

  9. bsgs算法详解

    例题  poj 2417bsgs  http://poj.org/problem?id=2417 这是一道bsgs题目,用bsgs算法,又称大小步(baby step giant step)算法,或者 ...

随机推荐

  1. c# 设计模式 之:策略模式

    算法与对象的耦合:     对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱...             动机:     在软件构建过程中,某些对象使用的算法可能多种多样,经常 ...

  2. eclipse工具的安装配置

    安装环境 系统:Windows7 软件:jre-8u73-windows-x64.exe,eclipse-inst-win64.exe Eclipse的安装过程 1.安装jre-8u73-window ...

  3. [C# | WinCE | Solution] 在 WinCE 上访问 SSL 加密后的 WCF SOAP 服务接口出现“未能与远程服务器建立信任关系”

    Scenario: 服务器的 SOAP 使用了 GeoTrust 签名的 EV 证书,WinCE调用时出现“未能与远程服务器建立信任关系”的错误.原因是该 WinCE 设备信任的证书包括 Global ...

  4. SQL Server 数据表代码创建约束

    约束 非空约束 --NN,ont null constraint 必须填写数据不能为空 --指定表 Student 添加名为NN_Student_sClassId非空约束(指定列名sClassId), ...

  5. 自定义UITabbarController控制器

    自定义UITabbarController控制器 这是定制UITabbarController的基本原理,没有进行功能性封装. 效果:   源码地址: https://github.com/YouXi ...

  6. CSS-定位属性

    Css学习——定位属性 定位可以看作是一种分层,通过对页面中的各种元素进行定位,可以将某些元素放到其他元素的上层,并在浏览器的窗口中设置这些元素的具体位置. position属性以及Css所提供的4中 ...

  7. ajax本地跨域请求以及解决方法

    什么是跨域?   我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景.所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源,只要没 ...

  8. quartz(转)

    1.   CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 ...

  9. AOP-切面是如何织入到目标对象中的

    切面是如何织入到目标对象中的???这大概是每个人在学习AOP的过程中都会产生的疑问吧. 当我们在调用目标方法时候,也就是通过代理对象调用目标方法的时候,比如:JdkDynamicAopProxy会通过 ...

  10. 动态代理与HOOK(与oc isa 替换)

    HOOK:面向函数,解决函数调用拦截与替换的问题: 动态代理:面向对象,解决对象的动态替换问题: 动态代理的实现方案: 1.经典代理机制: 2.子类化机制:oc语言的isa替换是这额解决方案的经典案例 ...