\(BSGS\)用于解决这样一类问题:

求解\(A^x ≡B(modP)\)的最小\(x\),其中\(P\)为质数。

这里我们采用分块的方法,把\(x\)分解为\(i *t-b\)(其中\(t\)是分块大小) 。根据模意义下逆元的性质,\(x\)的大小一定\(<=phi(p)\)即\(p - 1\),所以经过移项和进行存在性对比,我们就可以\(O(N)\)求出答案。

int BSGS (int A, int B, int P) {
int t = (int) ceil (sqrt (P));
for (int j = 0; j < t; ++j) {
mp[_mul (B, _pow (A, j, P), P)] = j;
//mp[ B * A ^ j ] = j;
}
A = _pow (A, t, P);
for (int i = 1; i <= t; ++i) {
int val = _pow (A, i, P);
//val = A^{i*t};
int j = mp.find (val) == mp.end () ? -1 : mp[val];
if (j >= 0) {
return i * t - j;
}
}
return -1;
}

上面这份代码中其实还可以把快速幂的\(log\)优化掉,可能会被卡常。

几个要注意的关键点:

  • 避免快速幂
  • 优化快速乘
  • 小心取模和\(longlong\)
  • \(p\)一定要是质数!
  • 建议手写哈希不然会多一个\(log\)(\(unordered\_map\)是不允许使用的)

\(exBSGS\)其实就是一个简单的扩展,把情况扩展到了\(p\)不是质数的情况,这种情况我们要先把\(P\)和\(A\)化为互质的状态。也就是说:对\(A\)和\(P\)取\(gcd\)直到其互质为止,从而化为如下形式:

\[(A/d)^{cnt} * A^{x}≡B/d^{cnt} (mod P/d^{cnt})
\]

其中,当\(B\)不能被二者的\(gcd\)整除时,就意味着原方程无解。

几个注意点:

  • 前面的\((A/d)^{cnt}\)同样需要统计进去
  • 要使用\(exgcd\)求解,因为可能不存在逆元。
  • 可能存在\(x==0\)的情况,记得特判
  • 快速乘,\(longlong\),取模,务必小心。
int exbsgs (int A, int B, int p) {
if (B == 1) return 0;
int _gcd, cnt = 0, res = 1;
while ((_gcd = gcd (A, p)) != 1) {
if (B % _gcd) return -1;
B /= _gcd, p /= _gcd, ++cnt;
res = ((res % p) * (A / _gcd)) % p;
if (res == B) return cnt;
}
int t = sqrt (p) + 1, tmp = 1;
Hash.clear ();
for (int i = 0; i < t; ++i) {
Hash[(tmp * B) % p] = i;
tmp = (tmp * A) % p;
}
res = (res * tmp) % p;
for (int i = 1; i <= t; ++i) {
if (Hash.find (res) != Hash.end ()) {
return i * t - Hash[res] + cnt;
}
res = (res * tmp) % p;
}
return -1;
}

BSGS与exBSGS学习笔记的更多相关文章

  1. exBSGS学习笔记

    exBSGS学习笔记 Tags:数学 题目的话就做下洛谷的模板好了 // luogu-judger-enable-o2 #include<algorithm> #include<io ...

  2. 数论算法 剩余系相关 学习笔记 (基础回顾,(ex)CRT,(ex)lucas,(ex)BSGS,原根与指标入门,高次剩余,Miller_Rabin+Pollard_Rho)

    注:转载本文须标明出处. 原文链接https://www.cnblogs.com/zhouzhendong/p/Number-theory.html 数论算法 剩余系相关 学习笔记 (基础回顾,(ex ...

  3. OI数学 简单学习笔记

    基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. PART1 数论部分 最大公约数 对于正整数x,y,最大的能同时整除它们的数称为最大公约数 常用的:\(lcm(x,y)=xy\ ...

  4. OI知识点|NOIP考点|省选考点|教程与学习笔记合集

    点亮技能树行动-- 本篇blog按照分类将网上写的OI知识点归纳了一下,然后会附上蒟蒻我的学习笔记或者是我认为写的不错的专题博客qwqwqwq(好吧,其实已经咕咕咕了...) 基础算法 贪心 枚举 分 ...

  5. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  6. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  7. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  8. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  9. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

随机推荐

  1. redis.clients.jedis.exceptions.JedisDataException :READONLY You can't write

    分布式直连同步调用测试时出现的错误:主从复制架构下,默认Slave是只读的,如果写入则会报错: redis.clients.jedis.exceptions.JedisDataException: R ...

  2. centos7优化启动项,关闭一些不必要开启的服务

    CentOS7已不再使用chkconfig 管理启动项 使用 systemctl list-unit-files 可以查看启动项 systemctl list-unit-files | grep en ...

  3. source 和 .

    Linux Source命令及脚本的执行方式解析 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile 对 ...

  4. JS 单线程和事件循环

    Js 是单线程,js代码从上到下依次执行,比如我们写了两个函数,肯定是上面的函数先执行,下面的函数后执行.但是这种单线程有一个非常大的问题,那就是遇到耗时的任务,后面的任务只能等待它执行完,才能进行. ...

  5. mysql-tar包搭建过程

    第一: wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz tar z ...

  6. Codeforces1071C Triple Flips 【构造】【Four Russians】

    题目分析: 这种题目显然可以先考虑哪些无解.我们发现我们不考虑操作次数的时候,我们可以选择连续的三个进行异或操作. 这样我们总能使得一个序列转化为$000...000xy$的形式.换句话说,对于$00 ...

  7. MT【256】2016四川高考解答压轴题

    (2016四川高考数学解答压轴题)设函数$f(x)=ax^2-a-\ln x,a\in R$. 1)讨论$f(x)$的单调性;2)确定$a$的所有可能值,使得$f(x)>\dfrac{1}{x} ...

  8. Hdoj 4508.湫湫系列故事——减肥记I 题解

    Problem Description 对于吃货来说,过年最幸福的事就是吃了,没有之一! 但是对于女生来说,卡路里(热量)是天敌啊! 资深美女湫湫深谙"胖来如山倒,胖去如抽丝"的道 ...

  9. Java 强制类型转换(类转换注意事项)

    将一个类型强制转换成另一个类型的过程被称为类型转换.例如: double x =3.14; int y = (int)x; 将表达式x的值转换成整数类型,舍弃小数部分. 有时候也可能是类的对象引用的转 ...

  10. bzoj1047/luogu2216 理想的正方形 (单调队列)

    开b组单调队列,分别维护此时某一列中的最大/最小值 然后我每次把它们的头取出来,塞到维护行的单调队列里,就是n*n的最大/最小值 #include<bits/stdc++.h> #defi ...