首页 > 编程语言 >「学习笔记」模运算与 BSGS 算法

「学习笔记」模运算与 BSGS 算法

时间:2023-06-04 18:22:05浏览次数:46  
标签:right int bmod 笔记 cdot 算法 quad left BSGS

取模

取模符号:\(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}}\)。

标签:right,int,bmod,笔记,cdot,算法,quad,left,BSGS
From: https://www.cnblogs.com/yifan0305/p/17454589.html

相关文章

  • flutter学习笔记(二)
    flutter一切皆widgetflutter和web前端的区别:1.js语法变成dart2.html标签变成组件widget3.flutter里没有css,只有各种widget的属性来实现样式(比如绝对定位用Stack组件来实现)fluter和web前端的相同点:1.dart语法接近js2.flutter里也可以实现flex弹性布局,用Expanded来实现(Expand......
  • 小迪安全web学习笔记(8)
    1、信息收集在安全测试中,信息收集是非常重要的一个环节,此环节的信息将影响到后续的成功几率,掌握信息的多少将决定发现漏洞机会大小,换言之决定着是否能完成目标的测试任务。也可以很直接的跟大家说:渗透测试的思路就是从信息收集这里开始。2、信息收集过程有无web 有CDN 国外请求......
  • 小迪安全web学习笔记(10)
    1、信息收集-资产信息github监控通过第三方软件监控你设定的最新漏洞信息并推送ctcms监控seo优化2、子域名挖掘3、补天漏洞响应平台用来攻击漏洞赚钱的平台。4、python脚本用来完成GitHub的监控,用信息搜集过程中得到得名称代入进脚本中运行,再下载推送得程序脚本再把它拖到相应......
  • 小迪安全web学习笔记(9)
    1、信息收集APP及其他资产APK:安卓应用程序包2、某IP无web框架下的第三方测试一阵扫描端口接口3、端口扫描工具速度:mas准确度:Nmap扫描ip用黑暗引擎:zoomeye子域名查看旁注查询4、类似域名接口查,查备案信息shodanfofa ......
  • 小迪安全web学习笔记(12)
    1、SQL注入数据库类型提交方法数据类型查询方法回显/盲注注入扩展WAF绕过防御方案2、mySQL简单注入危害:SQL注入可操控数据简易代码分析原理:通过参数传递把恶意代码传入sql语句中,让后面的代码显现出来。需要学习php、html、mySQL语句的基础知识去理解3、post注入的地方是输入账号......
  • 小迪安全web学习笔记(11)
    1、web漏洞-必懂知识点数据库的语句2、地址:网站域名、文件夹(目录)、文件参数名、参数值3、目录遍历漏洞跨目录文件的读取:/../../../文件名需要知道目录结构(怎样知道):工具扫描爬行通过网页源代码读4、漏洞等级和危害高危:SQL注入文件上传文件包含代码执行未授权访......
  • 【C#】加密算法
    一、理论1、https://zhuanlan.zhihu.com/p/4465815752、几种常用的加密方式 二、Aes加密“指定的密钥对此算法无效”建议您通过在AES类中使用LegalKeySizesproperty来检查密钥的有效大小。有效密钥大小由特定的对称算法实现指定,并在LegalKeySizes属性中列出。varkey......
  • 非对称加密DH算法,DH代码实现
    RSA算法原理(一)[url]http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html[/url]RSA算法原理(二)[url]http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html[/url]1976年,两位美国计算机学家WhitfieldDiffie和MartinHellma......
  • 【学习笔记】(18) 长链剖分
    长链剖分1.算法简介与性质长链剖分本质上就是另外一种链剖分方式。长链剖分与重链剖分有相通之处,后者是将子树大小最大的儿子作为重儿子,前者则是将子树深度最大的儿子作为重儿子。可见两者只是换了一个剖分形式。长链剖分有如下性质:性质1:每个节点所在长链末端为其子树......
  • 【学习笔记】(14) 初等数论(一)
    1.【最大公约数(GCD)和最小公倍数(LCM)】【基本性质、定理】\(\largegcd(a,b)=gcd(b,a−b)(a>b)\)\(\largegcd(a,b)=gcd(b,a\)\(\largemod\)\(b)\)\(\largegcd(a,b)\)\(\largelcm(a,b)=ab\)【推导结论】\(\largek|gcd(a,b)⟺k|a\)且\(k|b\)\(\larg......