取模

取模符号:\(x \bmod y\),表示 \(x\) 除以 \(y\) 得到的余数。

例如,

\[5 \bmod 3 = 2\\
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 - 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\) 处循环。

\[a^{p - 1 + k} \bmod p\\
\begin{aligned}
&= a^{p - 1} \cdot a^k \bmod p\\
&= a^k \bmod p
\end{aligned}
\]

对于该方程,要枚举 \(p - 1\) 个数,那我们将这 \(p - 1\) 个数分组,\(s\) 为每组的大小。

\[a_0 \quad a_1 \quad a_2 \cdots \quad a^{s - 1}\\
\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 算法的更多相关文章

  1. 「学习笔记」FFT 之优化——NTT

    目录 「学习笔记」FFT 之优化--NTT 前言 引入 快速数论变换--NTT 一些引申问题及解决方法 三模数 NTT 拆系数 FFT (MTT) 「学习笔记」FFT 之优化--NTT 前言 \(NT ...

  2. 「学习笔记」FFT 快速傅里叶变换

    目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...

  3. 「学习笔记」字符串基础:Hash,KMP与Trie

    「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...

  4. 「学习笔记」Min25筛

    「学习笔记」Min25筛 前言 周指导今天模拟赛五分钟秒第一题,十分钟说第二题是 \(\text{Min25}​\) 筛板子题,要不是第三题出题人数据范围给错了,周指导十五分钟就 \(\text{AK ...

  5. 「学习笔记」Treap

    「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...

  6. 「学习笔记」平衡树基础:Splay 和 Treap

    「学习笔记」平衡树基础:Splay 和 Treap 点击查看目录 目录 「学习笔记」平衡树基础:Splay 和 Treap 知识点 平衡树概述 Splay 旋转操作 Splay 操作 插入 \(x\) ...

  7. 「学习笔记」wqs二分/dp凸优化

    [学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...

  8. 「学习笔记」递推 & 递归

    引入 假设我们想计算 \(f(x) = x!\).除了简单的 for 循环,我们也可以使用递归. 递归是什么意思呢?我们可以把 \(f(x)\) 用 \(f(x - 1)\) 表示,即 \(f(x) ...

  9. 「学习笔记」ST表

    问题引入 先让我们看一个简单的问题,有N个元素,Q次操作,每次操作需要求出一段区间内的最大/小值. 这就是著名的RMQ问题. RMQ问题的解法有很多,如线段树.单调队列(某些情况下).ST表等.这里主 ...

  10. 「学习笔记」Fast Fourier Transform

    前言 快速傅里叶变换(\(\text{Fast Fourier Transform,FFT}\) )是一种能在\(O(n \log n)\)的时间内完成多项式乘法的算法,在\(OI\)中的应用很多,是 ...

随机推荐

  1. Redis事件机制(未写完)

    Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件: 文件事件:Redis通过套接字与客户端连接,文件事件是服务器对套接字操作的抽象. 时间事件:Redis服务器中的一些操作需要给定的时间 ...

  2. CZHA0黑客游戏

    一个自己开发的黑客游戏,里面用到了自研AC库 A0阶段: from ac import* from time import * from sys import * def printf(text): ...

  3. 怎么用ChatGPT写代码,ChatGPT怎么改代码修BUG

    ChatGPT 是一个自然语言处理模型,可以模拟人类语言生成文本,可以用于写代码和修复bug.在本文中,我们将介绍如何使用 ChatGPT 写代码和修bug. 怎么用ChatGPT写代码? 虽然 Ch ...

  4. mongodb图片上传 初识vue

    1.回顾 1.1 node node 服务器 url querystring express express 项目生成器 ejs 1.2 mongodb mongod --dbpath d:\data ...

  5. NEFU-NSILAB2021选拔赛WriteUp

    Web signin 打开看到源码: <?php highlight_file(__FILE__); $file = $_GET['file']; if ($file) { include $f ...

  6. 安装KubeOperator并导入现有集群进行管理

    安装KubeOperator并导入现有集群进行管理 介绍 KubeOperator 是一个开源的轻量级 Kubernetes 发行版,专注于帮助企业规划.部署和运营生产级别的 Kubernetes 集 ...

  7. [PKM] 家庭数据中心

    1 NAS(Network Attached Storage/网络附属存储) 1.1 NAS的定义 NAS(Network Attached Storage:网络附属存储):具备资料存储功能的装置.按 ...

  8. [Java SE]Unicode解码

    文由 将ASCII等其他非Unicode字符与Unicode混合的"脏的.不规范的"编码文本转为正常文本. 源码 unicodetoString(String unicodeTex ...

  9. DVWA上low级别反射型,存储型,DOM型XSS攻击获取用户cookie

    1.什么是反射型 XSS 攻击? 反射型 XSS 是指应用程序通过 Web 请求获取不可信赖的数据,并在未检验数据是否存在恶意代码的情况下,将其发送给用户. 反射型 XSS 一般可以由攻击者构造带有恶 ...

  10. 全网最详细中英文ChatGPT-GPT-4示例文档-人工智能助手从0到1快速入门——官网推荐的48种最佳应用场景(附python/node.js/curl命令源代码,小白也能学)

    目录 Introduce 简介 setting 设置 Prompt 提示 Sample response 回复样本 API request 接口请求 python接口请求示例 node.js接口请求示 ...