https://www.luogu.com.cn/problem/P3846

BSGS这个东西是用来干啥的?

形如下面这个式子:

\[a^b = c\;(mod\;p)
\]

其中:p是一个质数。\(2\leq a,b<p\leq2^{31}-1\)

求一个最小的正整数b,使得式子成立

首先,我们要知道一个东西。这个式子是有循环节的

根据费马小定理:p是质数,且a不是p的倍数时

有:\(a^{p-1}\equiv1\;(mod\;p)\)

而:\(a^0=1\)

因此答案是落在\([0,p-2]\)这个区间内的:


暴力:枚举b

时间复杂度:\(O(p) \;\;\;=>TLE\)


BSGS算法:

我们考虑将这个区间分块:

\[a^0,a^1,a^2,\cdots,a^{\sqrt{p}-1}
\]

\[a^{\sqrt{p}},a^{\sqrt{p}+1},\cdots,a^{2\sqrt{p}-1}
\]

\[\cdots
\]

\[a^{^{(\sqrt{p}-1)×\sqrt{p}}},\cdots,a^{p-1}
\]

然后我们进行下面的操作

①扫描第一行,若其中有答案,直接输出

②我们发现一个很显然的性质:第i行与第1行的同一列上的两个数,比值为:\(a^{(i-1)×\sqrt{p}}\)

若在第i行中,存在:

\[a^k=c\;(mod\;p)
\]

则说明在第一行中,存在:

\[a^r=\frac{c}{a^{(i-1)×\sqrt{p}}}
\]

而除(÷)操作,只需乘上它的逆元即可

根据费马小定理:

\[∵a^{p-1}\equiv1(mod\;p)
\]

\[∴a^{p-2}×a\equiv1(mod\;p)
\]

而\(a^{p-2}\)显然为a在模p意义下的逆元

因此:对于第i行,我们只需查询第一行。即可判断第i行是否存在答案。

这个东西直接用哈希即可在log的时间内实现

时间复杂度:

\[O(\sqrt{p}×log\;p)\;\;=> AC
\]

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std; #define int long long
int a,d,p,s[233333],sq;
map<int,int> mp;
int ksm(int a,int b,int mod)//快速幂
{
int ans=1;
while(b)
{
if(b&1)ans=1LL*ans*a%mod;
a=1LL*a*a%mod;
b>>=1;
}
return ans;
}
int BSGS()
{
sq=ceil(sqrt(p));
s[0]=1;mp[1]=0;
for(int i=1;i<=sq;i++)
{
s[i]=1LL*s[i-1]*a%p;
mp[s[i]]=i;
//用哈希表记录
if(s[i]==d)return i;
//若在第一行发现答案,直接输出
}
int dif=ksm(a,sq,p);
for(int l=sq+1,r=sq+sq,i=2;l<p;l+=sq,r+=sq,i++)
{
int inv=ksm(dif,i-1,p);
inv=ksm(inv,p-2,p);//求逆元
int t=1LL*d*inv%p;
if(mp.count(t))return mp[t]+(i-1)*sq;
//如果在第1行中查询存在,则说明第i行有答案
}
return -1;//说明无解
}
signed main()
{
scanf("%lld%lld%lld",&p,&a,&d);
if(d>=p||a>=p)//特殊情况
{
puts("no solution");
return 0;
}
int res=BSGS();
if(res==-1)puts("no solution");
else printf("%lld\n",res);
return 0;
}

Luogu P3846 BSGS算法的更多相关文章

  1. BSGS算法(大小步算法)

    $BSGS$ 算法 $Baby\ Steps\ Giant\ Steps$. 致力于解决给定两个互质的数 $a,\ p$ 求一个最小的非负整数 $x$ 使得 $a^x\equiv b(mod\ p)$ ...

  2. BSGS算法解析

    前置芝士: 1.快速幂(用于求一个数的幂次方) 2.STL里的map(快速查找) 详解 BSGS 算法适用于解决高次同余方程 \(a^x\equiv b (mod p)\) 由费马小定理可得 x &l ...

  3. 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法

    BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...

  4. bzoj2242: [SDOI2011]计算器 && BSGS 算法

    BSGS算法 给定y.z.p,计算满足yx mod p=z的最小非负整数x.p为质数(没法写数学公式,以下内容用心去感受吧) 设 x = i*m + j. 则 y^(j)≡z∗y^(-i*m)) (m ...

  5. [BSGS算法]纯水斐波那契数列

    学弟在OJ上加了道"非水斐波那契数列",求斐波那契第n项对1,000,000,007取模的值,n<=10^15,随便水过后我决定加一道升级版,说是升级版,其实也没什么变化,只 ...

  6. BSGS算法

    BSGS算法 我是看着\(ppl\)的博客学的,您可以先访问\(ppl\)的博客 Part1 BSGS算法 求解关于\(x\)的方程 \[y^x=z(mod\ p)\] 其中\((y,p)=1\) 做 ...

  7. BSGS算法及扩展

    BSGS算法 \(Baby Step Giant Step\)算法,即大步小步算法,缩写为\(BSGS\) 拔山盖世算法 它是用来解决这样一类问题 \(y^x = z (mod\ p)\),给定\(y ...

  8. uva11916 bsgs算法逆元模板,求逆元,组合计数

    其实思维难度不是很大,但是各种处理很麻烦,公式推导到最后就是一个bsgs算法解方程 /* 要给M行N列的网格染色,其中有B个不用染色,其他每个格子涂一种颜色,同一列上下两个格子不能染相同的颜色 涂色方 ...

  9. BSGS算法及其扩展

    bsgs算法: 我们在逆元里曾经讲到过如何用殴几里得求一个同余方程的整数解.而\(bsgs\)就是用来求一个指数同余方程的最小整数解的:也就是对于\(a^x\equiv b \mod p\) 我们可以 ...

随机推荐

  1. 初探Redis-基础类型String

    Redis存在五种基础类型:字符串(String).队列(List).哈希(Hash).集合(Set).有序集合(Sorted Set).String的出镜率算是最高的.本次列举出String的常用操 ...

  2. mysql 使用记录

    修改 mysql 数据库密码 mysqladmin -u username -h host_name password -P <port> "new_password" ...

  3. HBase可用性分析与高可用实践

    HBase作为一个分布式存储的数据库,它是如何保证可用性的呢?对于分布式系统的CAP问题,它是如何权衡的呢? 最重要的是,我们在生产实践中,又应该如何保证HBase服务的高可用呢? 下面我们来仔细分析 ...

  4. C语言指定初始化器解析及其应用

    指定初始化器的概念 C90 标准要求初始化程序中的元素以固定的顺序出现,与要初始化的数组或结构体中的元素顺序相同.但是在新标准 C99 中,增加了一个新的特性:指定初始化器.利用该特性可以初始化指定的 ...

  5. 一种特殊的生成器函数-Generator函数

    本节的内容,是建立在iterator遍历器知识的基础上.所以希望还没有看上一节的内容的话,最好还是看一看,当然你如果熟悉iterator就没有那个必要了. 既然你都看到这里来了,就咱们就接着往下讲.. ...

  6. UML由浅入深

    在UML 2.0的13种图形中,类图是使用频率最高的UML图之一.Martin Fowler在其著作<UML Distilled: A Brief Guide to the Standard O ...

  7. 2019-2020-1 20199325《Linux内核原理与分析》第十二周作业

    什么是ShellShock? Shellshock,又称Bashdoor,是在Unix中广泛使用的Bash shell中的一个安全漏洞,首次于2014年9月24日公开.许多互联网守护进程,如网页服务器 ...

  8. Python不同版本打包程序为.exe文件

    安装pyinstaller 测试用的python环境是3.6.2版本 下载地址 https://github.com/pyinstaller/pyinstaller/ 1.打开cmd,切到pyinst ...

  9. JVM原理与深度调优(一)

    什么是jvm jvm是java虚拟机 运行在用户态.通过应用程序实现java代码跨平台.与平台无关.实际上是"一次编译,到处执行" 1.从微观来说编译出来的是字节码!去到哪个平台都 ...

  10. 用百度AI平台接口实现OCR文字识别

    目录 一.接入指南 1.注册 2.登录 3.创建应用 二.安装接口模型 三.编写python代码 四.识别结果 一.接入指南 若想利用百度AI开放平台进行软件开发,首先应成为百度AI开放平台的开发者. ...