「学习笔记」模运算与 BSGS 算法
取模
取模符号:\(x \bmod y\),表示 \(x\) 除以 \(y\) 得到的余数。
例如,
7 \bmod 4 = 3\\
3 \bmod 3 = 0\\
\]
设 \(x\) 为被除数,\(y\) 为除数,\(z\) 为余数,则 \(x = k \cdot y + z, k = \lfloor \dfrac{x}{y} \rfloor\)。
模运算
\left (a - b \right ) \bmod c = \left (a \bmod c - b \bmod c \right ) \bmod c\\
\left (a \cdot b \right ) \bmod c = \left [\left (a \bmod c \right ) \cdot \left (b \bmod c \right ) \right ] \bmod c\\
\]
读入两个数 \(n, p\),现在求 \((n!) \bmod p\) 是多少?\((2 < p \le 10^9, 1 \le n \le 1000)\)
\(\left ( n! \right ) \bmod p = \left [ \left ( n - 1 \right )! \bmod p \times n \bmod p \right] \bmod p\)
#include <iostream>
using namespace std;
int n, p;
int main() {
cin >> n >> p;
int ans = 1;
for (int i = 1; i <= n; ++ i) {
ans = 1ll * ans * i % p;
}
cout << ans << endl;
return 0;
}
BSGS 算法
名称有很多,什么北上广深啊,等等,学名叫 baby-step giant-step,即大步小布算法。
我们由一个问题引入
给定三个数 \(a, b, p\),\(p\) 是质数,解方程 \(a^x \bmod p = b\)。\((a, b, p \le 10^9)\)
暴力的做法
int solve(int a, int b, int p) {
// O(p)
int v = 1;
for (int x = 0; x <= p - 2; ++ x) {
if (v == b) return x;
v = 1ll * v * a % p;
}
return -1;
}
由 \(a^{p - 1} \bmod p = 1\) 可知,余数会在 \(1\) 处循环。
\begin{aligned}
&= a^{p - 1} \cdot a^k \bmod p\\
&= a^k \bmod p
\end{aligned}
\]
对于该方程,要枚举 \(p - 1\) 个数,那我们将这 \(p - 1\) 个数分组,\(s\) 为每组的大小。
\Downarrow (\cdot a^s) \Uparrow (\div a^s)\\
a^s \quad a^{s + 1} \quad a^{s + 2} \cdots a^{2s - 1}\\
a^2s \quad a^{2s + 1} \quad a^{2s + 2} \cdots a^{3s - 1}\\
\]
若第 \(2\) 组数中出现了 \(b\),那么在第 \(1\) 组中,一定出现了 \(b \cdot a^{-s}\)。
#include <set>
using namespace std;
int solve(int a, int b, int p) {
int s = sqrt(p);
int v = 1;
set<int> se;
for (int i = 0; i < s; ++ i) {
se.insert(v);
v = 1ll * v * a % p;
}
// O(p / s)
for (int i = 0; i * s <= p; ++ i) { // 看答案是否在第 i 行里面
// 要看 b * a (-is) 是否在第 0 行出现
int c = 1ll * b * qpow(qpow(a, i * s, p), p - 2, p) % p;
if (se.count(c) != 0) {
int v = qpow(a, i * s, p); // 第 i 行的第一个数
for (int j = i * s; ; ++ j) { // O(s)
if (v == b) return j;
v = 1ll * v * a % p;
}
}
}
return -1;
}
复杂度为:\(O(\dfrac{p}{s} + s) = O(\max(\dfrac{p}{s}, s))\)
若取 \(s = \sqrt{p}\),则为 \(O_{\sqrt{p}}\)。
「学习笔记」模运算与 BSGS 算法的更多相关文章
- 「学习笔记」FFT 之优化——NTT
目录 「学习笔记」FFT 之优化--NTT 前言 引入 快速数论变换--NTT 一些引申问题及解决方法 三模数 NTT 拆系数 FFT (MTT) 「学习笔记」FFT 之优化--NTT 前言 \(NT ...
- 「学习笔记」FFT 快速傅里叶变换
目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...
- 「学习笔记」字符串基础:Hash,KMP与Trie
「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...
- 「学习笔记」Min25筛
「学习笔记」Min25筛 前言 周指导今天模拟赛五分钟秒第一题,十分钟说第二题是 \(\text{Min25}\) 筛板子题,要不是第三题出题人数据范围给错了,周指导十五分钟就 \(\text{AK ...
- 「学习笔记」Treap
「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...
- 「学习笔记」平衡树基础:Splay 和 Treap
「学习笔记」平衡树基础:Splay 和 Treap 点击查看目录 目录 「学习笔记」平衡树基础:Splay 和 Treap 知识点 平衡树概述 Splay 旋转操作 Splay 操作 插入 \(x\) ...
- 「学习笔记」wqs二分/dp凸优化
[学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...
- 「学习笔记」递推 & 递归
引入 假设我们想计算 \(f(x) = x!\).除了简单的 for 循环,我们也可以使用递归. 递归是什么意思呢?我们可以把 \(f(x)\) 用 \(f(x - 1)\) 表示,即 \(f(x) ...
- 「学习笔记」ST表
问题引入 先让我们看一个简单的问题,有N个元素,Q次操作,每次操作需要求出一段区间内的最大/小值. 这就是著名的RMQ问题. RMQ问题的解法有很多,如线段树.单调队列(某些情况下).ST表等.这里主 ...
- 「学习笔记」Fast Fourier Transform
前言 快速傅里叶变换(\(\text{Fast Fourier Transform,FFT}\) )是一种能在\(O(n \log n)\)的时间内完成多项式乘法的算法,在\(OI\)中的应用很多,是 ...
随机推荐
- 【深入浅出 Yarn 架构与实现】5-2 Yarn 三种调度器
本篇文章将深入介绍 Yarn 三种调度器.Yarn 本身作为资源管理和调度服务,其中的资源调度模块更是重中之重.下面将介绍 Yarn 中实现的调度器功能,以及内部执行逻辑. 一.简介 Yarn 最主要 ...
- 在 Vue 中控制表单输入
Vue中v-model的思路很简单.定义一个可响应式的text(通常是一个ref),然后用v-model="text"将这个值绑定到一个input上.这就创造了一个双向的数据流: ...
- vue之列表渲染v-for
目录 简介 用法 v-for可循环的几种变量的展示 数组的循环展示 对象的循环展示 字符串的循环展示 数字的循环展示 v-for搭档key值的说明 js循环几种方式 基于索引的循环 数组的循环 数组基 ...
- python入门教程之一 什么是python
python简介 1 什么是python Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页 ...
- dev-tools
Maven配置依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...
- 四月九号java知识
1.do{}while();和while(){}结构最主要区别就是前者后面要一个分号 2.System.out.print();与System.out.println();的区别后者输出换行, 前者不 ...
- day90:luffy:基于vue+drf的路飞学城项目前端部署
目录 1.域名备案 2.域名解析 3.设置安全组 4.部署架构图 5.一些准备工作 6.docker 7.把前端项目通过nginx容器来运行 后端部署传送门:基于vue+drf的路飞学城项目后端部署 ...
- CI框架调用第三方类库
public function index() { //调用第三方类库 /* * 注意事项: * library 里面调用的名字首字母必须是 大写 * 使用它的方法时 使用小写 */ $this-&g ...
- ArcGIS Pro发布地图服务(影像、矢量)
做GIS一般都是用ArcMap发布影像或者矢量服务,由于ArcGIS后续不在更新ArcMap,改用ArcGIS Pro,本文对ArcGIS Pro发布服务进行说明. 本文示例使用(因为portal的授 ...
- CTFshow愚人杯-被遗忘的反序列化
这题虽然只有100的分值,但是我觉得它涉及到的东西还蛮多的,写个随笔记录一下. 题目 <?php # 当前目录中有一个txt文件哦 error_reporting(0); show_source ...