BSGS算法_Baby steps giant steps算法(无扩展)详解
Giant Step-Astronauts(May'n・椎名慶治)
阅读时可以听听这两首歌,加深对这个算法的理解。(Baby steps少女时代翻唱过,这个原唱反而不是很有名……Giant Step就比较碉,是一个假面骑士片的插曲,由超碉的May'n和一个人建立的临时组合唱的,怕不怕)
这个主要是用来解决这个题:
A^x=B(mod C)(C是质数),都是整数,已知A、B、C求x。
我在网上看了好多介绍,觉得他们写得都不够碉,我看不懂…于是我也来写一发。
先把x=i*m+j,其中m=ceil(sqrt(C)),(ceil是向上取整)。
这样原式就变为A^(i*m+j)=B(mod C),
再变为A^j=B*A^(-m*i) (mod C),
先循环j=0~(C-1),把(A^j,j)加入hash表中,这个就是Baby Steps(现在可以播放Baby Steps-Varsity了)。
下面我们要做的是枚举等号右边,从hash表中找看看有没有,有的话就得到了一组i j,x=i*m+j,得到的这个就是正确解。
所以,接下来要解决的就是枚举B*A^(-m*i) (mod C)这一步(这就是Giant Step,快放Giant Step-Astronauts(May'n・椎名慶治))。
A^(-m*i)相当于1/(A^(m*i)),里面有除法,在mod里不能直接用除法,这时候我们就要求逆元。
/*百度百科:
对xA+yB=z,
变成这样xA = z - yB,取B=C(C就是我们要mod的那个)
推导出 xA % C = z %C
只要 z%C==1 时,就可以求出A的逆元x
但用exgcd求完,x可能是负数,还需要这样一下:x=(x%C+C)%C
//--exgcd介绍完毕--
再看我们的题目,
exgcd(A^(m*i) , C)=z,当C是质数的时候z肯定为1,这样exgcd求得的x就是逆元了。
因为x就是A^(m*i)的逆元,P/(A^(m*i))=P*x,所以
B*A^(-m*i) = B/(A^(m*i)) = B*x(mod C)
这样我们的式子A^j=B*A^(-m*i) (mod C)的等号右边就有了,就是B*x,就问你怕不怕!
枚举i,求出右边在hash里找,找到了就返回,无敌!
例题:
http://poj.org/problem?id=2417
代码:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define ll __int64
#define usint unsigned int
#define RE freopen("1.in","r",stdin) class hash {
public:
hash() {
memset(a,0xff,sizeof(a));
}
int locate(ll x) {
ll l=x%MOD;
while(a[l]!=x&&a[l]!=-) l=(l+)%MOD;
return l;
}
void insert(ll x,ll va) {
ll l=locate(x);
if(a[l]==-) {
a[l]=x;
v[l]=va;
}
}
ll get(ll x) {
ll l=locate(x);
return a[l]==x?v[l]:-;
}
void clear() {
memset(a,0xff,sizeof(a));
}
private:
static const ll MOD=;
ll a[MOD+],v[MOD+];
} S; ll exgcd(ll a,ll b,ll &x,ll &y) {
ll t,ret;
if (!b) {
x=,y=;
return a;
}
ret=exgcd(b,a%b,x,y);
t=x,x=y,y=t-a/b*y;
return ret;
} int main() {///A^x=B(modC) A^j=B*A^(-m*i)(mod C)
ll C,A,B;
ll m,i,t,D,ans,x,y;
while(scanf("%lld%lld%lld",&C,&A,&B)!=EOF) {
S.clear();
m=ceil(sqrt((double)C));
t=;
for(i=; i<m; i++) { /**One, two, baby steps.Three, four, baby steps.Five, six, baby steps.**/
S.insert(t,i);
t=t*A%C;
}
D=;///此时t=A^m
ans=-;
for(i=; i<m; i++) { /**一歩 Giant Step , 君にとってLittle だとしても**/
exgcd(D,C,x,y);///exgcd求逆元,得到x=D^(-i*m)
x=((x*B)%C+C)%C;///B*x=B*D^(-i*m)
y=S.get(x);
//printf("%lld,%lld\n",x,y);
if(y!=-) {
ans=i*m+y;
break;
}
D=(D*t)%C;///D=t^i,(t=A^m)
}
if(ans==-) printf("no solution\n");
else printf("%lld\n",ans);
}
return ;
}
BSGS算法_Baby steps giant steps算法(无扩展)详解的更多相关文章
- BSGS(Baby Steps,Giant Steps)算法详解
BSGS(Baby Steps,Giant Steps)算法详解 简介: 此算法用于求解 Ax≡B(mod C): 由费马小定理可知: x可以在O(C)的时间内求解: 在x=c之后又会循环: 而BS ...
- bsgs(Baby Steps Giant Steps)算法
BSGS算法(Baby Steps Giant Steps算法,大步小步算法,北上广深算法,拔山盖世算法) 适用问题 对于式子: $$x^y=z(mod_p)$$ 已知x,z,p,p为质数: 求解一个 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- BSGS_Baby steps giant steps算法
BSGS这个主要是用来解决这个题: A^x=B(mod C)(C是质数),都是整数,已知A.B.C求x. 在具体的题目中,C一般是所有可能事件的总数. 解: 设m = ceil(sqrt(C))(ce ...
- NOI / 2.5基本算法之搜索-6044:鸣人和佐助详解
总时间限制: 1000ms 内存限制: 65536kB 题目 佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢? 已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置.地图上的每个位置都可以走到, ...
- 二分算法题目训练(三)——Anton and Making Potions详解
codeforces734C——Anton and Making Potions详解 Anton and Making Potions 题目描述(google翻译) 安东正在玩一个非常有趣的电脑游戏, ...
- DOM对象控制HTML无素——详解3
创建元素节点createElement createElement()方法可创建元素节点.此方法可返回一个 Element 对象. 语法: document.createElement(tagName ...
- DOM对象控制HTML无素——详解2
节点属性 在文档对象模型 (DOM) 中,每个节点都是一个对象.DOM 节点有三个重要的属性 : 1. nodeName : 节点的名称 2. nodeValue :节点的值 3. nodeType ...
- DOM对象控制HTML无素——详解1
getElementsByName()方法 返回带有指定名称的节点对象的集合. 语法: document.getElementsByName(name) 与getElementById() 方法不同的 ...
随机推荐
- 实验5 简单嵌入式WEB服务器实验 实验报告 20135303 20135326
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级: 1353 姓名:20135303 魏昊卿 学号:2013532 ...
- 浪潮之巅——IT那点事之二—蓝色巨人IBM
蓝色巨人IBM的全称是国际商用机器公司(International Business Machines Corporation),纵观IBM的发展历史,可以看出IBM与机器结缘,以商用为主的发展策略. ...
- WPF之TreeList的实现方法(一)
做项目的时候根据需求,WPF现有的控件不能完全满足我们的需求, 很多时候我们需要对现有的控件做一下加工. 最简单的我们可能会把Tree转换成List形式有的叫Grid形式就像下图一样 今天我先做一个完 ...
- Windows 2008如何绑定MAC防范ARP攻击!
Windows 2008如何绑定MAC防范ARP攻击! 阅读(1974)暂无评论时间:2010-11-23 22:52:13 在Windows server 2003时代,通过arp 这命令即 ...
- linux下安装openssh-server
csdn博文地址:linux下安装openssh-server 点击进入 系统是ubuntu14.04,系统默认安装了openssh-client,但没有安装openssh-server,需要手动 ...
- 【Visual Studio】在VS2012中使用VSXtra
最近工作中需要把之前为VS 2010写的扩展迁移到VS 2012上.在将工程版本改为VS2012之后,代码没有修改,直接编译通过,也可以安装到VS2012上. 不过,在实际使用的时候,却报错,提示“T ...
- [BZOJ 2186][Sdoi2008]沙拉公主的困惑(欧拉函数)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2186 分析: 就是要求1~n!中与m!互质的数的个数 首先m!以内的就是φ(m!) 关 ...
- [BZOJ 2241][SDOI2011]打地鼠(枚举+预处理)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2241 分析: 鉴于R,C的取值很小,于是可以人为枚举R和C的大小,然后判定这个规格的锤 ...
- 第七章:Javascript数组
数组是值的有序结合.每个值叫做一个元素,而每个元素在数组中都有一个位置,用数字表示,称为索引. javascript数组是无类型的:数组的元素可以是任意类型,并且同一个数组中的不同元素也可能有不同的类 ...
- Solr -- 实时搜索
在solr中,实时搜索有3种方案 ①soft commit,这其实是近实时搜索,不能完全实时. ②RealTimeGet,这是实时,但只支持根据文档ID的查询. ③和第一种类似,只是触发softcom ...