问题:求$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。

代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. using namespace std;
  4. map<int,int> vis;
  5. int a,p,b;
  6. inline int gcd(int a,int b)
  7. {
  8. if(!b) return a;
  9. return gcd(b,a%b);
  10. }
  11. inline void exgcd(int a,int b,int &x,int &y)
  12. {
  13. if (!b) x=,y=;
  14. else{
  15. exgcd(b,a%b,x,y);
  16. int t=x;x=y;y=t-a/b*y;
  17. }
  18. }
  19. inline int inv(int a,int b)
  20. {
  21. int x,y;
  22. exgcd(a,b,x,y);
  23. return (x%b+b)%b;
  24. }
  25. inline int qcal(int a,int b,int p)
  26. {
  27. int res=;
  28. while(b)
  29. {
  30. if (b&) res=res*a%p;
  31. a=a*a%p;
  32. b>>=;
  33. }
  34. return res;
  35. }
  36. inline int bsgs(int a,int b,int p)
  37. {
  38. vis.clear();
  39. b%=p;
  40. int m=ceil(sqrt(p));
  41. for (int i=;i<=m;i++) b=b*a%p,vis[b]=i;
  42. b=;int tmp=qcal(a,m,p);
  43. for (int i=;i<=m;i++)
  44. {
  45. b=b*tmp%p;
  46. if (vis[b]) return (i*m-vis[b]+p)%p;
  47. }
  48. return -;
  49. }
  50. inline int exbsgs(int a,int b,int p)
  51. {
  52. if (b==||p==) return ;
  53. int g=gcd(a,p),k=,na=;
  54. while(g>)
  55. {
  56. if (b%g!=) return -;
  57. b/=g;p/=g;na=na*(a/g)%p;
  58. k++;
  59. if (na==b) return k;
  60. g=gcd(a,p);
  61. }
  62. int f=bsgs(a,b*inv(na,p)%p,p);
  63. if (f==-) return -;
  64. return f+k;
  65. }
  66. signed main()
  67. {
  68. cin>>a>>p>>b;
  69. while(a||p||b)
  70. {
  71. a%=p;b%=p;
  72. int t=exbsgs(a,b,p);
  73. if (t==-) puts("No Solution");
  74. else printf("%lld\n",t);
  75. cin>>a>>p>>b;
  76. }
  77. return ;
  78. }

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. Linux系统安装JDK8

    一.卸载现用的JDK 1.查看Linux自带的JDK是否已安装 查看是否安装openjdk,java  -version (yum安装的 一般都是 OpenJDK     命令:yum install ...

  2. day18 装饰器(下)+迭代器+生成器

    目录 一.有参装饰器 1 前提 2 如何使用有参装饰器 3 有参装饰器模板 4 修正装饰器 二.迭代器 1 什么是迭代器 2 为什么要有迭代器 3 如何用迭代器 3.1 可迭代对象 3.2 可迭代对象 ...

  3. Flask 基础组件(二):配置文件

    配置参数 flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为: { 'DEBUG': get_debug_flag(default=False), 是否开启 ...

  4. 一、Python系列——函数的应用之名片管理系统

    card_list = [] def main_desk(): print('*'*50) print('欢迎使用[名片管理系统]V1.0') print('1.新建名片') print('2.显示全 ...

  5. 尝鲜刚发布的 SpringFox 3.0.0,以前造的轮子可以不用了...

    最近 SpringFox 3.0.0 发布了,距离上一次大版本2.9.2足足有2年多时间了.可能看到这个名字,很多读者会有点陌生.但是,只要给大家看一下这两个依赖,你就知道了! <depende ...

  6. WYT的刷子

    WYT的刷子 题目描述 WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米:每列的高度单位也为米,由输入数据给出). 使用刷子的规则是: 与地面垂 ...

  7. IE11 CSS hack

    IE11 怎么做 CSS hack ? 很简单. @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { ...

  8. 题解 CF51F 【Caterpillar】

    根据毛毛虫的定义,我们不难发现在双连通分量中的点我们都需要进行合并操作,所以我们先进行\(tarjan\)缩边双连通分量,使原图变成一棵树,缩点对答案产生的贡献为每个双连通分量的\(size-1\) ...

  9. Spring Cloud Alibaba教程:Nacos

    Nacos是什么 Nacos 致力于帮助您发现.配置和管理微服务,它 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理. 注册中心 nacos-server 可以 ...

  10. android获取各种系统路径的方法

    链接https://blog.csdn.net/qq_26296197/article/details/51909423 通过Environment获取的 Environment.getDataDir ...