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算法,就是这样了;
例题:
代码:
#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)算法的更多相关文章
- BSGS(Baby Steps,Giant Steps)算法详解
BSGS(Baby Steps,Giant Steps)算法详解 简介: 此算法用于求解 Ax≡B(mod C): 由费马小定理可知: x可以在O(C)的时间内求解: 在x=c之后又会循环: 而BS ...
- 『高次同余方程 Baby Step Giant Step算法』
高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
- 【学习笔记】Baby Step Giant Step算法及其扩展
1. 引入 Baby Step Giant Step算法(简称BSGS),用于求解形如\(a^x\equiv b\pmod p\)(\(a,b,p\in \mathbb{N}\))的同余方程,即著名的 ...
- 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 ...
- 解高次同余方程 (A^x=B(mod C),0<=x<C)Baby Step Giant Step算法
先给出我所参考的两个链接: http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 (AC神,数论帝 扩展Baby Step Gian ...
- HDU 2815 Mod Tree 离散对数 扩张Baby Step Giant Step算法
联系:http://acm.hdu.edu.cn/showproblem.php?pid=2815 意甲冠军: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...
- HDU 2815 扩展baby step giant step 算法
题目大意就是求 a^x = b(mod c) 中的x 用一般的baby step giant step 算法会超时 这里参考的是http://hi.baidu.com/aekdycoin/item/2 ...
- BSGS算法_Baby steps giant steps算法(无扩展)详解
Baby Steps-Varsity Giant Step-Astronauts(May'n・椎名慶治) 阅读时可以听听这两首歌,加深对这个算法的理解.(Baby steps少女时代翻唱过,这个原唱反 ...
- BSGS_Baby steps giant steps算法
BSGS这个主要是用来解决这个题: A^x=B(mod C)(C是质数),都是整数,已知A.B.C求x. 在具体的题目中,C一般是所有可能事件的总数. 解: 设m = ceil(sqrt(C))(ce ...
随机推荐
- C++与C的区别一
1. C++风格数组初始化: #include <iostream> #include <array> using namespace std; void main() { / ...
- delphi 10.2 ----简单的递归函数例子求和
unit Unit10; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...
- iOS 本地时间 / UTC时间 / 时间戳等操作 / 获取当前年月日
//获得当前时间并且转为字符串 - (NSString *)dateTransformToTimeString { NSDate *currentDate = [NSDate date];//获得当前 ...
- JS设计模式之单体模式(Singleton)
单体模式作为一种软件开发模式在众多面向对象语言中得到了广泛的使用,在javascript中,单体模式也是使用非常广泛的,但是由于javascript语言拥有其独特的面向对象方式,导致其和一些传统面向对 ...
- 1.需要对txt存放的测试数据做去重处理,代码如下
采用集合去重,在新文件里逐行写入,达成目的 old_file = "D:/testdata/memberId.txt" #old result_file = "D:/te ...
- Luogu P1351 联合权值 题解
这是一个不错的树形结构的题,由于本蒟蒻不会推什么神奇的公式其实是懒得推...,所以很愉快的发现其实只需要两个点之间的关系为祖父和儿子.或者是兄弟即可. 然后问题就变得很简单了,只需要做一个正常的DFS ...
- 剑指offer——面试题32.1:分行从上到下打印二叉树
void BFSLayer(BinaryTreeNode* pRoot) { if(pRoot==nullptr) return; queue<BinaryTreeNode*> pNode ...
- (转)分布式中使用Redis实现Session共享(一)
上一篇介绍了如何使用nginx+iis部署一个简单的分布式系统,文章结尾留下了几个问题,其中一个是"如何解决多站点下Session共享".这篇文章将会介绍如何使用Redis,下一篇 ...
- 从svn检出项目的注意事项
提交到svn的时候,选择忽略.project,.settings,.classpath等文件,检出项目的时候就不能选择 [做为工作作为工作空间的项目检出].而应该选择做为新项目检出. 然后选择工程的类 ...
- MySQL存储引擎 InnoDB与MyISAM的区别
来源:http://www.jb51.net/article/47597.htm 基本的差别:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行 ...