洛谷 P4861 按钮
房间的铁门上有一个按钮,还有一个显示屏显示着“1”。
旁边还有一行小字:“这是一个高精度M进制计算器,每按一次按钮,屏幕上的数便会乘以K。当个位数再次变为1时,门就开了。”
由于Ada急于出去,所以你要在1s之内求出她的最小按键次数。
首先我们看到题目,每次在M进制下对1乘k,也就是对k乘方,最后还是得到1
这样我们就可以列出同余方程kx≡1 (mod M)
而初始状态为1,即k0=1
所以答案就是满足方程的最小的正整数x
其实这道题是Ex\_BSGS,因为题目不满足k和M互质
考虑我们在做Ex\_BSGS时,每次取出g=gcd(k,M),b′=bg,M′=Mg,k′=kg
得到新方程kx−1×k′≡b′ (mod M′)
移项得到kx−1≡b′k′ (mod M′)
无解的情况就是g∤并且b\ne1
证明就不证了,不会的可以去看这篇文章QAQ
直到g=1,即k,M互质,就可以用BSGS求解了
而题目给的b是1,那么我们回去看这个过程,k,M不互质说明g>1
g>1,x\ne0\Rightarrow g\nmid b\Rightarrow \text{无解}
所以这个题特判下k,M互不互质然后跑BSGS就好了
简单说下BSGS怎么写吧
设n=\left \lfloor \sqrt M \right \rfloor,x=i\times n-j,1\le i,j\le n,原方程就变为
k^{i\times n-j}\equiv 1\ (mod\ M)
(k^n)^i\equiv k^j\ (mod\ M)
然后把k^j求出来哈希一下就可以啦
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cmath>
#define int long long
using namespace std;
int m,k;
map <int,int> f;
int mypow(int a,int x,int p) //快速幂
{
int s=1;
while (x)
{
if (x&1)s=s*a%p;
a=a*a%p;
x>>=1;
}
return s;
}
int gcd(int a,int b) //最大公约数
{
if (!b)return a;
return gcd(b,a%b);
}
signed main()
{
cin>>m>>k;
if (gcd(m,k)!=1) //特判无解
{
cout<<"Let's go Blue Jays!"<<endl;
return 0;
}
int n=ceil(sqrt(m)),b=1;
for (int i=1;i<=n;i++) //k^j
{
b=b*k%m;
f[b]=i;
}
b=1;
int tmp=mypow(k,n,m);
for (int i=1;i<=n;i++) //(k^n)^i
{
b=b*tmp%m;
if (f[b]&&(i*n-f[b]+m)%m!=0) //有解且不为0
{
cout<<(i*n-f[b]+m)%m<<endl;
return 0;
}
}
cout<<"Let's go Blue Jays!"<<endl; //无解
return 0;
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档