BSGS算法(Baby Steps Giant Steps算法,大步小步算法,北上广深算法,拔山盖世算法)

适用问题

对于式子:

$$x^y=z(mod_p)$$

已知x,z,p,p为质数;

求解一个最小非负整数y;



存在一个y,属于[0,p-2](费马小定理)

于是有了一个笨拙的方法,枚举y

枚举y,期望效率:O(P)

寻求一种优化:

对式子变型:

设:$$y=i\sqrt{p}-j$$

则$$x^{i\sqrt{p}-j}=z(mod_p)$$

——这个变型的用意在于把y拆开

枚举y,变成枚举,i,j;

i在1~$\sqrt{p}$之间,j在0~$\sqrt{p}$之间

(根号上取整,其实i,j的范围大可大些——只要保证y不会小于0)

枚举(i,j),期望效率:$O(\sqrt{p}*\sqrt{}p)$

本质上没有优化

接着变型:

$$x^{i\sqrt{p}}=z*x^{j}(mod_p)$$ 

——这个变型的用意在于真正把y分离为两部分

枚举j,把等号右边的模后得数置于hash_table,此时同一个得数只留最大的j值;

从小到大枚举i,计算等号左边的模后得数,查询hash_table,第一个成功查询的i,与其相应的j,组成$i\sqrt{p}-j$即为最小的y,

期望效率:$O(\sqrt{p}*T(hash))$

效率优异,拔山盖世的bsgs算法,就是这样了;



例题:

[SDOI2011]计算器

代码:

#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
const int ss=;
using namespace std;
int hash_tab[],tot;
struct ss{
int nu,next,j;
}data[];
void work();
void work1();
void work2();
void work3();
LL Sqr(LL ,int );
int hash(int, int ,int );
LL z,y,p;
bool flag;
int main()
{
work();
}
void work(){
int T,K;
scanf("%d%d",&T,&K);
while(T--){
scanf("%lld%lld%lld",&y,&z,&p);
if(K==)
work1();
if(K==)
work2();
if(K==)
work3();
}
}
void work1(){
int i,j,k;
printf("%lld\n",Sqr(y,z));
}
void work2(){
int ans,less;
if((!(y%p)&&z)||((y%p)&&!z)){
printf("Orz, I cannot find x!\n");return;
}
printf("%lld\n",Sqr(y%p,p-)*z%p);
}
void work3(){
long long ysqrtp,sqrtp=ceil(sqrt(p));
memset(hash_tab,,sizeof(hash_tab));
memset(data,,sizeof(data));
long long l=,r=z%p;
int i,j;
if((!(y%p)&&z)||((y%p)&&!z)){
printf("Orz, I cannot find x!\n");return;
}
ysqrtp=Sqr(y,sqrtp);
for(i=;i<=sqrtp;i++)
hash(r,i,),(r*=y)%=p;
for(i=;i<=sqrtp;i++){
(l*=ysqrtp)%=p;
if((j=hash(l,,))!=-){
printf("%lld\n",i*sqrtp-j);
return ;
}
}
printf("Orz, I cannot find x!\n");
}
LL Sqr(LL x,int n){
LL ret=;
while(n){
if(n&)(ret*=x)%=p;
(x*=x)%=p;n>>=;
}
return ret;
}
int hash(int num,int j,int flag){
int tem;
for(tem=hash_tab[num%ss];tem;tem=data[tem].next){
if(data[tem].nu==num){
if(!flag&&j>data[tem].j)
data[tem].j=j;
return data[tem].j;
}
if(!data[tem].next&&!flag){
data[tem].next=++tot;
data[tot].j=j;
data[tot].nu=num;
return -;
}
}
if(!flag){
hash_tab[num%ss]=++tot;
data[tot].j=j;
data[tot].nu=num;
}
return -;
}

bsgs(Baby Steps Giant Steps)算法的更多相关文章

  1. BSGS(Baby Steps,Giant Steps)算法详解

    BSGS(Baby Steps,Giant Steps)算法详解 简介: 此算法用于求解 Ax≡B(mod C): 由费马小定理可知: x可以在O(C)的时间内求解:  在x=c之后又会循环: 而BS ...

  2. 『高次同余方程 Baby Step Giant Step算法』

    高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...

  3. 【学习笔记】Baby Step Giant Step算法及其扩展

    1. 引入 Baby Step Giant Step算法(简称BSGS),用于求解形如\(a^x\equiv b\pmod p\)(\(a,b,p\in \mathbb{N}\))的同余方程,即著名的 ...

  4. POJ 3243 Clever Y (求解高次同余方程A^x=B(mod C) Baby Step Giant Step算法)

    不理解Baby Step Giant Step算法,请戳: http://www.cnblogs.com/chenxiwenruo/p/3554885.html #include <iostre ...

  5. 解高次同余方程 (A^x=B(mod C),0<=x<C)Baby Step Giant Step算法

    先给出我所参考的两个链接: http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 (AC神,数论帝  扩展Baby Step Gian ...

  6. HDU 2815 Mod Tree 离散对数 扩张Baby Step Giant Step算法

    联系:http://acm.hdu.edu.cn/showproblem.php?pid=2815 意甲冠军: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...

  7. HDU 2815 扩展baby step giant step 算法

    题目大意就是求 a^x = b(mod c) 中的x 用一般的baby step giant step 算法会超时 这里参考的是http://hi.baidu.com/aekdycoin/item/2 ...

  8. BSGS算法_Baby steps giant steps算法(无扩展)详解

    Baby Steps-Varsity Giant Step-Astronauts(May'n・椎名慶治) 阅读时可以听听这两首歌,加深对这个算法的理解.(Baby steps少女时代翻唱过,这个原唱反 ...

  9. BSGS_Baby steps giant steps算法

    BSGS这个主要是用来解决这个题: A^x=B(mod C)(C是质数),都是整数,已知A.B.C求x. 在具体的题目中,C一般是所有可能事件的总数. 解: 设m = ceil(sqrt(C))(ce ...

随机推荐

  1. SpringData JPA实现CRUD,分页与多参数排序

    Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库.Map-Reduce 框架.云数据服务等等,SpringData JPA是简化创建 JPA ...

  2. 嵌入式C语言自我修养 05:零长度数组

    5.1 什么是零长度数组 顾名思义,零长度数组就是长度为0的数组. ANSI C 标准规定:定义一个数组时,数组的长度必须是一个常数,即数组的长度在编译的时候是确定的.在ANSI C 中定义一个数组的 ...

  3. 洛谷P3980 [NOI2008]志愿者招募

    题解 最小费用最大流 每一天是一条边\((inf-a[i], 0)\) 然后对于一类志愿者, 区间两端连一条\((inf, c[i])\) \(S\)向第一个点连\((inf, 0)\) 最后一个点向 ...

  4. 问题 K: 周期串plus

    问题 K: 周期串plus 时间限制: 1 Sec  内存限制: 128 MB提交: 682  解决: 237[提交] [状态] [命题人:外部导入] 题目描述 如果一个字符串可以由某个长度为k的字符 ...

  5. Go语言类型转换

    类型转换用于将一种数据类型的变量转换为另外一种类型的变量. Go语言类型转换基本格式如下:表达式 T(v) 将值 v 转换为类型 T . Go语言各种类型转换及函数的高级用法:strconv包实现了基 ...

  6. PHP-GD库开发手记

    创建带有alpha通道的背景输出图像画中文字体获取长宽等比例缩放图片,也可以用于裁切实例代码 创建带有alpha通道的背景 $png = imagecreatetruecolor(800, 600); ...

  7. Highcharts图表.net版开源,支持webform 和 mvc3,完全开源

    Highcharts是一个制作图表的纯Javascript类库,主要特性如下: 兼容性:兼容当今所有的浏览器,包括iPhone.IE和火狐等等: 对个人用户完全免费: 纯JS,无BS: 支持大部分的图 ...

  8. C# 文件操作系列一

    在.Net环境中,所有关于文件操作的类都在System.IO命名空间下,注:在修改文件时,安全性显得格外重要,但是本随笔不过多讲述安全性,这里假设我们有足够的权限. 1.管理文件系统 先通过一幅图来了 ...

  9. interceptor&filter

    1.基于 filter基于filter接口中的doFilter回调函数: interceptor则基于Java本身的反射机制: 2.与servlet关系 filter是依赖于servlet容器的,没有 ...

  10. nuxt.js引入客户端脚本和第三方库出现window/document/ navigator未定义问题

    官方文档中已经给出解决方案: 实际操作也比较简单,比如我之前在项目中引入的wangeditor,这个插件里包含了navigator内容 解决:现在nuxt.config.js的webpack扩展配置中 ...