bsgs(Baby Steps Giant Steps)算法

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=999983; 
using namespace std;
int hash_tab[1000000],tot;
struct ss{int nu,next,j;
}data[1000000];
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==1)work1();if(K==2)work2();if(K==3)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-2)*z%p);
}
void work3(){long long ysqrtp,sqrtp=ceil(sqrt(p));memset(hash_tab,0,sizeof(hash_tab));memset(data,0,sizeof(data));long long l=1,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=0;i<=sqrtp;i++)hash(r,i,0),(r*=y)%=p;for(i=1;i<=sqrtp;i++){(l*=ysqrtp)%=p;if((j=hash(l,0,1))!=-1){printf("%lld\n",i*sqrtp-j);return ;}}printf("Orz, I cannot find x!\n");
}
LL Sqr(LL x,int n){LL ret=1;while(n){if(n&1)(ret*=x)%=p;(x*=x)%=p;n>>=1;}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 -1;}}if(!flag){hash_tab[num%ss]=++tot;data[tot].j=j;data[tot].nu=num;}return -1;
}
View Code

 

转载于:https://www.cnblogs.com/nietzsche-oier/p/7493671.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/415927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2003服务器远程桌面连不上解决办法

一直都是用XP 连2003服务器&#xff0c;以前从未出现过问题&#xff0c;早二天突然出现提示&#xff1a;什么许可还有多少天到期&#xff0c;也没当回事&#xff0c;想想以前都这样&#xff0c;也没出过什么问题啊&#xff0c;于是就有了今天的一幕&#xff0c;打开远程桌面连接…

vue-cli webpack 打包报错:Unexpected token: punc (()

本来项目完美打包&#xff0c;后来我增加了一个插件vue-ionicons&#xff0c;打包build就是报错&#xff1a; ERROR in static/js/8.017e5cf2d2f1a552890d.js from UglifyJs Unexpected token: punc (() [./node_modules/vue-ionicons/dist/ionicons-mixin.js:7,0][static/js/…

Head First设计模式之备忘录模式

一、定义 不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态 二、结构 备忘录模式中主要有三类角色&#xff1a; 发起人角色&#xff1a;记录当前时刻的内部状态&#xff0c;负责创建和…

SVN 405错误

SVN提交时报http 错误号405&#xff1a;http 405资源被禁止 分析&#xff1a;这是因为服务器上已经存在同名的目录了&#xff0c;所以你提交时会报错。 出现 原因&#xff1a;创建目录的时候&#xff0c;多创建了一个&#xff0c;所以在Server端就删掉一个。 解决办法&#…

centos 生产 ssh-key

注意:必须在用户目录下的.ssh文件夹下生成公私密钥 1、进入目录 cd /root/.ssh2、生成ssh-key ssh-keygen -t rsa3、打开查看 vim /root/.ssh/id_rsa.pub

SVN更新时报403错误

最近开发组使用&#xff33;&#xff36;&#xff2e;更新时经常会提示403错误&#xff0c;上网查了好久&#xff0c;说是权限的问题&#xff0c;但我感觉不象&#xff0c;可以提交&#xff0c;可以迁出&#xff0c;但就是更新时报错&#xff0c;如果是权限的问题&#xff0c;那…

【模板】树状数组2

题目 基本介绍模板题目代码实现基本介绍 这篇是树状数组模板2 主要内容有&#xff1a; 1.将某区间每一个数数加上x 2.求出某一个数的和 也就是说支持区间修改 我们可以看一下 Qi.DC 的想法 他说&#xff1a;“ 我们在树状数组中可以用前 i 项的和来表示第 i 个数 那么当对 …

mpvue 从零开始 女友初成长 0

我的女友叫mpvue&#xff0c;为什么不选择原生的&#xff0c;或者wepy呢&#xff0c;因为我只喜欢mpvue。 0、首先你得保证先安装了vue-cli npm install --g vue-cli1、脚手架构建项目&#xff0c;我直接在当前项目中创建&#xff0c;一路Y就可以创建项目了。 vue init mpvu…

Android 隐藏状态栏,沉浸式状态栏,状态栏背景色,状态栏字体色,透明状态工具类

设置状态栏颜色 if (Build.VERSION.SDK_INT>21){getWindow().setStatusBarColor(getResources().getColor(R.color.mainc)); } 方法2 <color name"colorPrimary">#3F51B5</color> //取消标题 requestWindowFeature(Window.FEATURE_NO_TITLE); /…

SVN错误信息汇总

Subversion 错误信息一览表 注意&#xff1a; 不同的客户端&#xff08;命令行&#xff0c;TortoiseSVN, AnkhSVN, Subclipse等&#xff09;的出错信息可能稍有不同。 下面表格中的出错信息以 http://svn.moon.ossxp.com/svn/test 版本库做示例&#xff0c;仅供参考。 编…

二项分布 , 多项分布, 以及与之对应的beta分布和狄利克雷分布

1. 二项分布与beta分布对应   2. 多项分布与狄利克雷分布对应 3. 二项分布是什么&#xff1f;n次bernuli试验服从 二项分布 二项分布是N次重复bernuli试验结果的分布。 bernuli实验是什么&#xff1f;做一次抛硬币实验&#xff0c;该试验结果只有2种情况&#xff0c;x 1, 表示…

mpvue 从零开始 女友的衣装 1 pages

pages文件夹就像一个大橱柜&#xff0c;里面放着各种精美的衣装&#xff0c;你也可以理解为供小程序的页面。 1、制造衣服 我在pages页面下新建了3个页面 market 广告市场task 任务中心my 个人中心 以market为例&#xff0c;写最简单的代码 <template><div class…

android 动态设置View的高度和宽度,ViewTreeObserver使用

private int mMonitorHeight 0; private int mMonitorWidth 0; private boolean bisSetScreen false; 动态设置满屏宽度 ViewTreeObserver vto2 monitor.getViewTreeObserver(); vto2.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){Overridep…

Oracle RDA(Remote Diagnostic Agent) 工具说明

Oracle RDA(Remote Diagnostic Agent) 工具说明 分类&#xff1a; Oracle 性能调优 Oracle 高级知识 一.RDA 说明 RDA(RemoteDiagnostic Agent)是oracle用来收集、分析数据库的工具&#xff0c;运行该工具不会改变系统的任何参数&#xff0c;RDA收集的相关数据非常全面&…

替换元素节点replaceChild()

replaceChild 实现子节点(对象)的替换。返回被替换对象的引用。 语法&#xff1a; node.replaceChild (newnode,oldnew ) 参数&#xff1a; newnode : 必需&#xff0c;用于替换 oldnew 的对象。 oldnew : 必需&#xff0c;被 newnode 替换的对象。 注意: 1. 当 oldnode 被替…