高次同余方程 $BSGS$
第一篇\(Blog\)...
还是决定把\(luogu\)上的那篇搬过来了。
BSGS,又名北上广深
它可以用来求\(a^x \equiv b (mod \ n)\)这个同余方程的一个解,其中\(a,n\)互质。
欧拉定理告诉我们,这里\(a^{\varphi(n)} \equiv 1 (mod \ n)\)
由于\(a^0 \equiv 1 (mod \ n)\),所以这里\(x\)到\(\varphi(n)\)后\(a^x \ mod \ n\)就开始循环了。
所以我们最坏情况就是\(n\)为素数时,从\(0\)到\(n-1\)枚举\(x\)就行了。
这样我们就得到了一个\(O(n)\)复杂度的优秀算法。
然而\(n < 2^{31}\)......
我们考虑让\(x = im - j(0 \le j \le m)\),即把\(0...n-1\)这\(n\)个数按每块大小为\(m\)分块。
就有
\]
两边同时乘\(a^j\)得
\]
对于等式右边,总共只会有\(m+1\)种不同的\(j\),我们把\(ba^0,ba^1,...,ba^m\)全塞到一个\(map\)里,\(i\)也只会有\(\lceil \frac{n}{m} \rceil\)种取值,直接暴力。
最后复杂度为\(O(m + \lceil\frac{n}{m} \rceil)\)
取\(m = \lceil \sqrt{n} \rceil\),就可以做到\(O(\sqrt{n})\)
当然,用\(map\)的话还要乘上一个\(log\)。
其实分块的时候\(j\)取到\(m\)可能会导致有些\(x\)被考虑到两次,但并不影响,而且边界还不怎么需要处理。
贴一下Luogu P3846(板子题)的代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int fpow(int a, int b, int c){
int ret = 1;
for (a %= c; b; b>>=1, a = 1ll*a*a % c) if (b&1) ret = 1ll * ret * a % c;
return ret;
}
int BSGS(int a, int b, int n, int &ret) {
int m = ceil(sqrt(n));
map<int,int> h;
for (int i = 0, tmp = b%n; i <= m; i++, tmp = 1ll*tmp*a%n)
h[tmp] = i;
a = fpow(a, m, n);
for (int tmp = a, i = 1; i <= m; i++, tmp = 1ll*tmp*a%n)
if (h.count(tmp)) { ret = 1ll*i*m - h[tmp]; return 1; }
return 0;
}
int main(){
int a, b, n, flg, ans; scanf("%d%d%d", &n, &a, &b);
flg = BSGS(a, b, n, ans);
if (!flg) puts("no solution"); else printf("%d\n", ans);
return 0;
}
还有比较毒瘤的就是如果\(a \equiv 0 (mod \ n)\)的时候,需要特判\(b \not\equiv 0 (mod \ n)\)
因为如果\(a\)是\(n\)的倍数,那怎么乘都是\(0\)...
所以板子在这里:
int BSGS(int a, int b, int n, int &ret) {
a %= n, b %= n;
if (a == 0) { if (b == 0) { ret = 0; return 1; } else return 0; }
int m = ceil(sqrt(n)); map<int,int> h;
for (int tmp = b%n, i = 0; i <= m; i++, tmp = 1ll*tmp*a % n) h[tmp] = i;
a = fpow(a, m, n);
for (int tmp = a%n, i = 1; i <= m; i++, tmp = 1ll*tmp*a % n)
if (h.count(tmp)) { ret = 1ll*i*m - h[tmp]; return 1; }
return 0;
}
\(ExBSGS\)的话。。。改天学吧 感觉也没什么用
高次同余方程 $BSGS$的更多相关文章
- ACM_高次同余方程
/*poj 3243 *解决高次同余方程的应用,已知 X^Y = K mod Z, 及X,Z,K的值,求 Y 的值 */ #include<cstdio> #include<cstr ...
- 数论之高次同余方程(Baby Step Giant Step + 拓展BSGS)
什么叫高次同余方程?说白了就是解决这样一个问题: A^x=B(mod C),求最小的x值. baby step giant step算法 题目条件:C是素数(事实上,A与C互质就可以.为什么?在BSG ...
- HDU1452Happy 2004(高次幂取模+积性函数+逆元)
题目意思:2004^x的所有正因数的和(S)对29求余:输出结果: 原题链接 题目解析:解析参照来源:点击打开链接 因子和 6的因子是1,2,3,6; 6的因子和是s(6)=1+2+3+6=12; 2 ...
- 【解高次同余方程】51nod1038 X^A Mod P
1038 X^A Mod P 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 X^A mod P = B,其中P为质数.给出P和A B,求< P的所有X. 例如:P = 11 ...
- 『高次同余方程 Baby Step Giant Step算法』
高次同余方程 一般来说,高次同余方程分\(a^x \equiv b(mod\ p)\)和\(x^a \equiv b(mod\ p)\)两种,其中后者的难度较大,本片博客仅将介绍第一类方程的解决方法. ...
- 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)
注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...
- 51Nod1039 N^3 Mod P 数论 原根 BSGS
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1039.html 题目传送门 - 51Nod1039 题意 题解 这题我用求高次剩余的做法,要卡常数. ...
- 51Nod1038 X^A Mod P 数论 原根 BSGS
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1038.html 题目传送门 - 51Nod1038 题意 题解 在模质数意义下,求高次剩余,模板题. ...
- CF1106F Lunar New Year and a Recursive Sequence 原根、矩阵快速幂、BSGS
传送门 好久没写数论题了写一次调了1h 首先发现递推式是一个乘方的形式,线性递推和矩阵快速幂似乎都做不了,那么是否能够把乘方运算变成加法运算和乘法运算呢? 使用原根!学过\(NTT\)的都知道\(99 ...
随机推荐
- SciPy 图像处理
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- Day5 - G - The Unique MST POJ - 1679
Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...
- 013-PHP输出表格
<?php // 数据表格化 print("<TABLE bgcolor='ffccoo' BORDER=\"1\">\n"); // 表格开 ...
- Educational Codeforces Round 64 选做
感觉这场比赛题目质量挺高(A 全场最佳),难度也不小.虽然 unr 后就懒得打了. A. Inscribed Figures 题意 给你若干个图形,每个图形为三角形.圆形或正方形,第 \(i\) 个图 ...
- Arrays类常用方法
Arrays类 3.1 概述 java.util.Arrays 此类包含用来操作数组的各种方法,比如排序和搜索等.其所有方法均为静态方法. 3.2 操作数组的方法 1.将参数数组变成字符串 publi ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-question-sign
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- POJ 1655:Balancing Act
Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10311 Accepted: 4261 De ...
- HihoCoder第十四周:无间道之并查集
#1066 : 无间道之并查集 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 这天天气晴朗.阳光明媚.鸟语花香,空气中弥漫着春天的气息--额,说远了,总之,小Hi和小H ...
- R 读取excel的方法
1.加载 readxl 包,利用 reade_excel() 函数 install.packages("readxl") library(readxl) data = read_e ...
- mcu运行时间估算
昨个伙计问我他那个板子的程序运行时间估算问题… 现在说一下估算的思路.首先确定有几个点,板子的主频.时钟周期,机器周期. 首先由主频f得到一个时钟周期为1/f. 再者时钟周期与机器周期有一个比例关系, ...