问题:求$a^x\equiv b\ (mod\ p)$的最小正整数解。

这时候就要用到BSGS(拔山盖世)算法。直接进入正题:

设$x=im-n$,

则原式等于$a^{im-n}\equiv b\ (mod\ p)$。

移项,得$a^{im}\equiv a^nb(mod\ p)$。

我们把所有$a^nb$的状态存到一个map里,然后枚举$a^{im}$,如果相等则找到最小正整数解。

当$m=\sqrt p$时,算法效率最高。则$[1,m]$枚举$n$,$[1,m]$枚举$i$。

以上说的情况是$a$与$p$互质的情况。那么不互质该怎么做呢?

我们变换一下形式:$a*a^{x-1}\equiv b\ (mod\ p)$。

移项,得$a*a^{x-1}+y*p=b$。

设$g=gcd(a,p)$,由裴蜀定理得,如果$b\ mod\ p≠0$,那么此同余方程无解。

左右两边同除$g$,得到$\frac{a}{g}*a^{x-1}+y*\frac{p}{g}=\frac{b}{g}$,即$a^{x-1}\equiv \frac{b}{g}*(\frac{a}{g})^{-1}\ (mod\ \frac{p}{g})$

重复上述步骤,直到$gcd(a,p)=1$为止,然后就可以用普通的BSGS求啦。

注意要特判一下,如果$b=1$或$p=1$或者某一时刻$(\frac{a}{g})^x=b'$,那么直接返回$0$即可。

注意各种情况下的模数!!!被这个坑了好久QAQ。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
map<int,int> vis;
int a,p,b;
inline int gcd(int a,int b)
{
if(!b) return a;
return gcd(b,a%b);
}
inline void exgcd(int a,int b,int &x,int &y)
{
if (!b) x=,y=;
else{
exgcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
}
}
inline int inv(int a,int b)
{
int x,y;
exgcd(a,b,x,y);
return (x%b+b)%b;
}
inline int qcal(int a,int b,int p)
{
int res=;
while(b)
{
if (b&) res=res*a%p;
a=a*a%p;
b>>=;
}
return res;
}
inline int bsgs(int a,int b,int p)
{
vis.clear();
b%=p;
int m=ceil(sqrt(p));
for (int i=;i<=m;i++) b=b*a%p,vis[b]=i;
b=;int tmp=qcal(a,m,p);
for (int i=;i<=m;i++)
{
b=b*tmp%p;
if (vis[b]) return (i*m-vis[b]+p)%p;
}
return -;
}
inline int exbsgs(int a,int b,int p)
{
if (b==||p==) return ;
int g=gcd(a,p),k=,na=;
while(g>)
{
if (b%g!=) return -;
b/=g;p/=g;na=na*(a/g)%p;
k++;
if (na==b) return k;
g=gcd(a,p);
}
int f=bsgs(a,b*inv(na,p)%p,p);
if (f==-) return -;
return f+k;
}
signed main()
{
cin>>a>>p>>b;
while(a||p||b)
{
a%=p;b%=p;
int t=exbsgs(a,b,p);
if (t==-) puts("No Solution");
else printf("%lld\n",t);
cin>>a>>p>>b;
}
return ;
}

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

  1. 大步小步法(BSGS) 学习笔记

    \(\\\) BSGS 用于求解关于 \(x\) 的方程: \[ a^x\equiv b\pmod p\ ,\ (p,a)=1 \] 一般求解的是模意义下的指数,也就是最小非负整数解. \(\\\) ...

  2. BSGS学习笔记

    用于求\(A^{x} \equiv B \pmod{C}\) 高次方程的最小正整数解x,其中C为素数 引理1:$a^{i\mod\varphi(p) } \equiv a^{i} $ (mod p) ...

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

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

  4. OI数学 简单学习笔记

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. SpringBoot+Mybatis一级缓存和二级缓存详解

    本文主要介绍在SpringBoot项目中如何使用Mybatis的一级.二级缓存,为了演示方便,本文的数据库采用H2内存数据库,数据库连接池默认使用SpringBoot2.X自带的hikariCP. 正 ...

  2. day17 生成器, 面向过程, 三元表达式, 生成式

    1. 生成器 生成器:就是一种自定义的迭代器,是用来返回多次值自定义迭代器的好处:节省内存 return只能返回一次值,函数就立即结束了yield 1.可以挂起函数,保存函数的运行状态 2.可以用来返 ...

  3. 从0开始,手把手教你使用React开发答题App

    项目演示地址 项目演示地址 项目源码 项目源码 其他版本教程 Vue版本 小程序版本 项目代码结构 前言 React 框架的优雅不言而喻,组件化的编程思想使得React框架开发的项目代码简洁,易懂,但 ...

  4. Java 线程池中的线程复用是如何实现的?

    前几天,技术群里有个群友问了一个关于线程池的问题,内容如图所示: 关于线程池相关知识可以先看下这篇:为什么阿里巴巴Java开发手册中强制要求线程池不允许使用Executors创建? 那么就来和大家探讨 ...

  5. Prometheus + Grafana 监控系统搭

    本文主要介绍基于Prometheus + Grafana 监控Linux服务器. 一.Prometheus 概述(略) 与其他监控系统对比 1 Prometheus vs. Zabbix Zabbix ...

  6. Python-02 可视化之tkinter介绍

    1 控件介绍 1.1 Label import tkinter as tk # 使用Tkinter前需要先导入 window = tk.Tk() window.title('My Window') w ...

  7. 数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?

    https://zhuanlan.zhihu.com/p/75462046 对于初学者,总是会把度量值和计算列搞混,我也经常碰到这样的问题,有些星友用文章中的代码总是报错,发给我一看,才知道TA把本来 ...

  8. 三种安装python第三方库的方法

    ​    还记得第一天的时候我们说python拥有丰富的库,那这么多的第三方库,我们如何使用呢?今天我们可以看一下python库的安装. 方法一:使用python命令进行离线安装 我以urllib5库 ...

  9. 关于Java8的精心总结

    前言 ​ 最近公司里比较新的项目里面,看到了很多关于java8新特性的用法,由于之前自己对java8的新特性不是很了解也没有去做深入研究,所以最近就系统的去学习了一下,然后总结了一篇文章第一时间和大家 ...

  10. Spring-Boot 多数据源配置+动态数据源切换+多数据源事物配置实现主从数据库存储分离

    一.基础介绍 多数据源字面意思,比如说二个数据库,甚至不同类型的数据库.在用SpringBoot开发项目时,随着业务量的扩大,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源. ...