「学习笔记」BSGS

这篇具有很好参考价值的文章主要介绍了「学习笔记」BSGS。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

「学习笔记」BSGS

点击查看目录
目录
  • 「学习笔记」BSGS
    • Baby-step Giant-step
      • 问题
      • 算法
    • 例题
      • Discrete Logging
        • 代码
      • P3306 [SDOI2013] 随机数生成器
        • 思路
      • P2485 [SDOI2011]计算器
        • 思路
      • Matrix
        • 思路
        • 代码

Baby-step Giant-step

问题

\(O(\sqrt{p})\) 的时间内求解

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

其中 \(a\perp p\),方程的解 \(x\) 满足 \(0 \le x < p\)

算法

首先根据费马小定理 \(a^{p-1}\equiv1\pmod{p}\),不难发现 \(1\sim p-1\) 是一个循环节,也就是说只用判断 \(1\sim p-1\) 这些数里是否存在一个方程的解 \(x\) 即可。

但是这个范围仍然很大,直接 \(O(p)\) 跑肯定不行。

\(x=A\left\lceil\sqrt{p}\right\rceil-B (0\le A, B\le\left\lceil\sqrt{p}\right\rceil)\),则 \(a^{A\left\lceil\sqrt{p}\right\rceil-B} \equiv b \pmod p\)

\(a^{A\left\lceil\sqrt{p}\right\rceil} \equiv a^{B} b \pmod p\)

由于 \(A,B\) 不大,我们可以枚举出所有 \(a^{B} b\)\(a^{A\left\lceil\sqrt{p}\right\rceil}\) 的取值。用 map 存下所有 \(a^{B} b\) 的取值,再查找 \(a^{A\left\lceil\sqrt{p}\right\rceil}\) 的取值是否出现过即可。

注意在求出满足 \(a^{A\left\lceil\sqrt{p}\right\rceil} \equiv a^{B} b \pmod p\) 的合法 \(A,B\) 后还要推回到 \(a^{A\left\lceil\sqrt{p}\right\rceil-B} \equiv b \pmod p\) 才能得到解 \(x=A\left\lceil\sqrt{p}\right\rceil-B (0\le A, B\le\left\lceil\sqrt{p}\right\rceil)\),这一步要求 \(a\perp p\),但不要求 \(p\in\mathbb{P}\)

时间复杂度:\(O(\sqrt{p}\log_2\sqrt{p})\)

你想更快的话你用哈希表也行。

例题

Discrete Logging

板子题,放一份代码。

代码

点击查看代码
inline ll FastPow (ll a, ll b, ll P) {
	ll ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % P;
		a = a * a % P, b >>= 1;
	}
	return ans;
}
inline void Solve () {
	ll qp = ceil (sqrt (p));
	_for (i, 0, qp) h[n * FastPow (b, i, p) % p] = i;
	ll t = FastPow (b, qp, p), num = 1;
	_for (i, 1, qp) {
		num = num * t % p;
		if (h[num]) {
			ans = (i * qp % p - h[num] + p) % p;
			return;
		}
	}
	return;
}

P3306 [SDOI2013] 随机数生成器

思路

推式子题。

\[\begin{aligned} x_{i} &\equiv x_{i-1}a+b \pmod{p}\\ &\equiv (x_{i-2}a+b)a+b \pmod{p}\\ &\equiv x_{i-2}a^2+ab+b \pmod{p}\\ &\equiv (x_{i-3}a+b)a^2+ab+b \pmod{p}\\ &\equiv x_{i-3}a^3+a^2b+ab+b \pmod{p}\\ &\equiv x_{1}a^{i-1}+b(\sum_{k=0}^{i-2}a^{k}) \pmod{p}\\ &\equiv x_{1}a^{i-1}+b\frac{1-a^{i-2}}{1-a} \pmod{p}\\ \end{aligned} \]

那么:

\[\begin{aligned} x_{1}a^{i-1}+b\frac{a^{i-1}-1}{a-1} &\equiv t \pmod{p}\\ x_{1}a^{i-1}+\frac{a^{i-1}b}{a-1} - \frac{b}{a-1} &\equiv t \pmod{p}\\ a^{i-1}(x_{1}+\frac{b}{a-1}) &\equiv t + \frac{b}{a-1} \pmod{p}\\ a^{i-1} &\equiv \frac{t + \frac{b}{a-1}}{x_{1}+\frac{b}{a-1}} \pmod{p}\\ \end{aligned} \]

\(i - 1 = A \left \lceil \sqrt p \right \rceil - B\),则 \(a^{A \left \lceil \sqrt p \right \rceil - B} \equiv \dfrac{t + \frac{b}{a-1}}{x_{1}+\frac{b}{a-1}} \pmod{p}\)

则:

\[\begin{aligned} a^{A \left \lceil \sqrt p \right \rceil} &\equiv a^{B}\dfrac{t + \frac{b}{a-1}}{x_{1}+\frac{b}{a-1}} \pmod{p} \end{aligned} \]

就可以跑 BSGS 了。

但是还有几个细节:

  • \(x1=t\):答案为 \(1\)
  • \(a=0\):如果 \(b=t\),答案为 \(2\),否则为 \(-1\)
  • \(a=1\):此时 \(x_i=x_1+(i-1)b\),算逆元即可。

P2485 [SDOI2011]计算器

思路

是不是再来一个 CRT 就同余全家桶了。

裸的逆元和 BSGS,但是题目只保证 \(p\in\mathbb{P}\) 不保证 \(y\perp p\),需要特判一下 \(p\) 是否为 \(y\) 的倍数。

if (!y) { ans = (z % p ? -1 : 1); return; }

Matrix

思路

定义一个矩阵的类然后直接跑就行,感觉没啥大区别。文章来源地址https://www.toymoban.com/news/detail-409725.html

代码

点击查看代码
const ll N = 110;
namespace SOLVE {
	ll n, p, ans;
	class Matrix {
	public:
		ll len, m, ma[N][N];
		inline void Init (ll l, ll md) {
			len = l, m = md;
			memset (ma, 0, sizeof (ma));
			_for (i, 1, l) ma[i][i] = 1;
			return;
		}
		inline void Print () {
			_for (i, 1, n) {
				_for (j, 1, n) {
					printf ("%lld ", ma[i][j]);
				}
				puts ("");
			}
			puts ("");
			return;
		}

		ll* operator [] (ll x) { return ma[x]; }
		Matrix operator * (Matrix another) const {
			Matrix ans;
			ans.Init (len, m);
			memset (ans.ma, 0, sizeof (ans.ma));
			_for (i, 1, len) _for (j, 1, len) _for (k, 1, len)
				ans[i][j] = (ans[i][j] + ma[i][k] * another[k][j] % m) % m;
			return ans;
		}
		bool operator == (Matrix another) const {
			_for (i, 1, n) _for (j, 1, n) if (ma[i][j] != another[i][j]) return 0;
			return 1;
		}
		bool operator < (Matrix another) const {
			_for (i, 1, len) _for (j, 1, len) {
				if (ma[i][j] < another[i][j]) return 1;
				if (ma[i][j] > another[i][j]) return 0;
			}
			return 0;
		}
	} a, b;
	std::map <Matrix, ll> mp;

	inline ll rnt () {
		ll x = 0, w = 1; char c = getchar ();
		while (!isdigit (c)) { if (c == '-') w = -1; c = getchar (); }
		while (isdigit (c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar ();
		return x * w;
	}

	inline Matrix FastPow (Matrix a, ll b, ll P) {
		Matrix ans;
		ans.Init (n, P);
		while (b) {
			if (b & 1) ans = ans * a;
			a = a * a, b >>= 1;
		}
		return ans;
	}

	inline void In () {
		n = rnt (), p = rnt ();
		a.Init (n, p), b.Init (n, p);
		_for (i, 1, n) _for (j, 1, n) a[i][j] = rnt ();
		_for (i, 1, n) _for (j, 1, n) b[i][j] = rnt ();
		return;
	}
	inline void Solve () {
		ll qp = ceil (sqrt (p));
		_for (i, 0, qp) mp[b] = i, b = b * a;
		a = FastPow (a, qp, p);
		Matrix mat; mat.Init (n, p);
		_for (i, 1, qp) {
			mat = mat * a;
			if (mp[mat]) {
				ans = (i * qp % p - mp[mat] + p) % p;
				return;
			}
		}
		return;
	}
	inline void Out () {
		printf ("%lld\n", ans);
		return;
	}
}

到了这里,关于「学习笔记」BSGS的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 手机查看IGES,STP,STEP格式3D模型免费APP推荐-CAD Assistant

    CAD Assistant官网网址:CAD Assistant - Open Cascade Open Cascade CAD Assistant 是一款功能强大的离线 3D CAD 查看器和转换器,具有简单直观的界面,可免费用于个人和商业用途。目前已被全球成千上万的移动设备和台式机终端用户视为快速便捷的 3D 查看器。CAD Assistant基于开源库(Open CAS

    2024年02月12日
    浏览(164)
  • Python个人学习笔记目录

    以下目录基于黑马程序员B站视频个人学习笔记 正在更新中……

    2024年01月21日
    浏览(33)
  • 目录IO 2月19日学习笔记

     1. lseek        off_t lseek(int fd, off_t offset, int whence);        功能:             重新设定文件描述符的偏移量        参数:             fd:文件描述符             offset:偏移量             whence:                 SEEK_SET    文件开头                 SEEK_CUR    文件当前

    2024年02月20日
    浏览(28)
  • 【Python_PySide学习笔记(目录)】

    下面是专栏的目录汇总: 序号 标题 1 【Python_PySide2学习笔记(一)】PySide2动态加载UI方式,重写关闭窗体事件 2 【Python_PySide2学习笔记(二)】QTabWidget 添加布局LayoutQTabWidget内控件大小自适应父窗体大小 3 【Python_PySide2学习笔记(三)】QPushButton设置背景图片 4 【Python_PySide

    2024年01月24日
    浏览(35)
  • Linux 学习笔记(2)—— 关于文件和目录

    目录 1、切换目录 2、查看系统信息 3、文本的创建和编辑 3-1)创建文件  3-2)查看文件 3-3)输出重定向和追加重定向等 3-4)使用 vi 编辑器编辑文件 4、文件和文件夹的处理 4-1)对文件的处理  4-2)查看目录信息 4-3)对目录的操作 5、文件查找 6、查找文件中的内容 7、使用

    2024年02月09日
    浏览(63)
  • 虚幻学习笔记2—点击场景3D物体的两种处理方式

    一、前言         本文使用的虚幻引擎为5.3.2,两种方式分别为:点击根物体和精准点击目标物体。 二、实现 2.1、玩家控制器中勾选鼠标点击事件:这一步很重要,如图2.1.1所示:在自定义玩家控制器中勾 图2.1.1 选该项,此时鼠标即可点击3D场景中的物体。 2.2、给自定义A

    2024年01月19日
    浏览(37)
  • 安卓学习笔记:安卓11访问/读写 Android/data 目录

    省流提示:采用android studio工具开发,记录一次低级的开发,避免以后忘记或者踩坑。 最近有个业余项目开发到一小半,过程中需要读写 Android/data目录的文件,采用常规的文件操作总是提示权限被拒绝,无奈上网参考了很多资料,终于得到了解决。 无法访问Android/data 的原因

    2024年02月13日
    浏览(36)
  • Linux shell编程学习笔记6:查看和设置变量的常用命令

    上节我们介绍了变量的变量命名规则、变量类型、使用变量时要注意的事项,今天我们学习一下查看和设置变量的一些常用命令,包括变量的提升,有些命令在之前的实例中已经使用过了。 语法格式:echo [参数] [输出内容] 常用参数: -e:支持反斜线控制的字符转换(具体参

    2024年02月07日
    浏览(38)
  • 2022/10/16今日问题:(点击下方目录可直接跳转)

    这些问题都是在写作业过程中碰到的,记录下来,以后可以翻阅,也希望可以给有同样问题的人答疑解惑。本人新手,多有不熟、不严谨、不规范的地方,希望大家多多指正。如果对于问题有更好的解决方法也欢迎分享。 目录 问题一、一个Textview组件中的文本被前面的组件挡

    2024年02月16日
    浏览(37)
  • js 点击图片实现查看大图

    点击图片放大缩小(遮罩)

    2024年02月05日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包