首页 > 编程语言 >BSGS exBSGS 详解(大步小步算法)

BSGS exBSGS 详解(大步小步算法)

时间:2022-09-03 10:45:16浏览次数:51  
标签:frac int res exBSGS 详解 return equiv 互质 BSGS

我放弃挣扎了

至少除了这个点,我的 BSGS exBSGS 都是可以过的,我就姑且当它没有问题了!

BSGS : Big Step Giant Step

额其实我也不懂这个算法和名字有什么关系,倒是有点根号分治的味道~

这个东西用来求解一个东西 \(x\) 使得:

\[a^x \equiv b \pmod p \]

其中 \(a,b,p\) 给定且 \(p\) 为质数

接下来直接上操作:

令 $$t = \left \lceil \sqrt{p}\right \rceil $$

令 $$x = i \times t - B$$ 那么由于 \(p\) 是质数所以我们可以进行一番操作将原式变形为 $$a^{i\times t - B} \equiv b \pmod p$$

进一步得到

\[a^{i\times t} \equiv b^B \pmod p \]

注意!!!

这一步是进行了除法,必须保证逆元存在,而这等价于 \(a^B,p\) 互质,进而等价于 \(a,p\) 互质,所以其实只要求 \(a,p\) 互质即可!!

然后发现这里的 \(i \in [1,t] , B \in [0,t]\) 所以这两个东东都是 \(\sqrt{p}\) 级别的。那么考虑将右边的 \(b^B\) 插入哈希表记录对应的 \(B\) ,然后 \(O(\sqrt{p})\) 枚举左边的 \(a^{i\times t}\) 查询对应的哈希表即可。然后注意特判 \(i \times t - B \ge 0\) 即可

unordered_map<int,int>mp;
int BSGS(int a,int b,int p){
	mp.clear();	
	int t = ceil(sqrt(p)),res = b;
	rep(i,0,t){
		mp[res] = i;
		res = 1ll * res * a % p;
	}
	int base = ksm(a,t,p);res = base;
	if(a == 0)return b == 0 ? 1 : -1;
	rep(i,1,t){
		if(mp.count(res)){
//其实这样常数飞快,但是好像就是这种不用快速幂的方法导致了 wa 
//改了就变成TLE了,所以可以自行更改
			if(i * t - mp[res] >= 0)return i * t - mp[res];
		}
		res = 1ll * res * base % p;
	}
	return -1;
}

exBSGS

这里其实就是把 \(p\) 扩展到任意数了。

那么这里的 \(a,p\) 不互质了,我们考虑把他变成互质的不就好了!

重新观察式子

\[a^{x} \equiv b \pmod p \]

首先令 \(g = \gcd (a,p)\)

方程可以变为

\[\frac{a}{g} \times a^{x-1} \equiv \frac{b}{g} \pmod {\frac{p}{g}} \]

无解情况的话就是 \(g \nmid b\) 且 \(b \ne 1\) 因为 \(b = 1\) 直接 \(x = 0\) 就好了,别的手推下不定方程很好证明。

于是我们可以重复这个过程,直至 \(\gcd (a,p) = 1\) 并且得到了 \(k\) 个 \(g\)

令 $u = {\textstyle \prod_{i=1}^{k}} \frac{a}{g_{i}} ,v = \textstyle \prod_{i=1}^{k}g_{i} $你会发现每个 \(\frac {a}{g_{i}}\) 都与现在的 \(\frac{p}{v}\) 互质,因为 \(\frac{p}{v}\) 现在与 \(a\) 互质,自然与 \(\frac{a}{g_{i}}\) 互质,所以 \(u\) 与 \(p\) 互质,所以存在逆元。

\[a^{x-k} \times u \equiv \frac{b}{v } \pmod {\frac{p}{v}} \]

\[a^{x-k} \equiv \frac{b}{uv} \pmod {\frac{p}{v}} \]

所以算一下 \(u\) 的逆元,这个就变成了普通的 BSGS 辣!

void exgcd(int a,int b,int &d,int &x,int &y){
	if(!b){
		d = a;x = 1;y = 0;return;
	}
	exgcd(b,a%b,d,y,x);
	y -= x * (a / b);
}
inline int inv(int a,int p){
	int d,x,y;
	exgcd(a,p,d,x,y);
	return (x % p + p) % p;
}
int exBSGS(int a,int b,int p){
	if(b == 1 || p == 1)return 0;
	int g = __gcd(a,p),k = 0,mul = 1;
	while(g > 1){
		if(b % g)return -1;
		++k;b /= g;p /= g;
		mul = mul * (a / g) % p;
		if(mul == b)return k;
		g = __gcd(a,p);
	}
	int x = BSGS(a,b * inv(mul,p) % p,p);
	if(x == -1)return x;
	return x + k;
}

标签:frac,int,res,exBSGS,详解,return,equiv,互质,BSGS
From: https://www.cnblogs.com/wsxxs/p/16652116.html

相关文章

  • Go语言 指针详解
    现在就开始你的Go语言学习之旅吧!人生苦短,let’sGo.指针是一个代表着某个内存地址的值,这个内存地址往往是在内存中存储的另一个变量的值的起始位置.Go语言对指针的......
  • Java自定义Annotation注解开发详解
    Java自定义Annotation注解开发详解目录介绍一、运行期的自定义注解1.ClassLevelAnnotation2.MethodLevelAnnotation3.FieldLevelAnnotation4.使用自定义......
  • 用例设计方法之因果图详解
    一、因果图概述因果图是从需求中找出因(输入条件)和果(输出或程序状态的改变),通过分析输入条件之间的关系(组合关系、约束关系等)及输入和输出之间的关系绘制出因果图,再转化成......
  • git rebase详解(图解+最简单示例,一次就懂)
    引言网上有太多讲rebase和merge的文章,但大多都是复制粘贴没有自己的理解,而且很多博客的例子写的过于复杂,让人没兴趣看下去。本文举最简洁的例子,大白话几句就让你快速掌握......
  • Python 的四种共享传参详解
    Python唯一支持的参数传递方式为共享传参(callbysharing),传递参数一共有四种传递方式,分别为:位置参数,默关键字参数和可变参数,其中可变参数分为两种(*args和**kargs)。一、......
  • git rebase详解(图解+最简单示例,一次就懂)
    引言网上有太多讲rebase和merge的文章,但大多都是复制粘贴没有自己的理解,而且很多博客的例子写的过于复杂,让人没兴趣看下去。本文举最简洁的例子,大白话几句就让你快速掌握re......
  • 自动填写体温脚本详解
    最近疫情又严重了起来,学校要求每天都要上报我们的早、中、晚体温情况,但是我们居然被要求中午就提供全天的体温,这很明显是一个纯纯欺上瞒下的工程。为了不每天浪费时间来扫......
  • MySQL Explain执行计划key_len详解(特意针对date和datetime详细测试说明)
    MySQLExplain执行计划key_len详解(特意针对date和datetime详细测试说明)我们在使用Explain查看SQL执行计划时,其中有一列为key_kenkey_len表示使用的索引长度,那么key_len......
  • session、cookie、token详解
    授权:给客户端授予权限鉴权:鉴定是否有访问权限1、会话会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户......
  • vue项目中main.js使用方法详解
    vue项目中main.js使用方法详解目录第一部分:main.js文件解析第二部分:Vue.use的作用以及什么时候使用Vue.use是什么?(官方文档)Vue.use()什么时候使用?补充:关于main.js方便小技......