2023.1.16[模板]BSGS/exBSGS
2023.1.16 [模板]BSGS/exBSGS
全称Boy Step Girl Step
给定一个质数 p,以及一个整数 a,一个整数 b,现在要求你计算一个最小的非负整数 l,
满足\(a^x \equiv b (mod p)\)
算法流程
设t = \(\lceil \sqrt p \rceil\) ,x = i * t - m (0\(\leq\)i\(\leq\)t , 0\(\leq\)m\(\lt\)t - 1)
\(a^{i * t - b} \equiv b\) (mod p)
\(({a^t})^i \equiv b * a^m\) (mod p)
我们建立一个map,将b * \(a^0\) ~ b * \(a^{t - 1}\) 全部推进去,将值与指数建立映射关系,然后再枚举i,递推算出左式,判断map中是否有值,如果有值则返回答案ans = i * t - map[val]
时间复杂度O(\(\sqrt p\))
inline int BSGS(int a,int b,int p)//a ^ x = b (% p)
{
map <int,int> q;
int t = sqrt(p);
for(int i = 0;i <= t - 1;i++)
q[(1ll * ksm(a,i,p) * b % p)] = i;
int c = ksm(a,t,p);
for(int i = 1;i <= t;i++)
{
int now = ksm(c,i,p);
if(q.find(now) != q.end())
{
int x = q[now];
return i * t - x;
}
}
return -1;
}
exBSGS
那么如果a,p不互质呢?
设d = gcd(a,p);
对于一个同余方程\(a^x \equiv b\) (mod p)
我们可以把它转化成二元一次不定方程的形式 \(a^x\) + py = b
给a分离系数得到 a\(a^{x-1}\) + py = b
想办法消去d,\(\frac ad a^{x-1} + \frac pd y = \frac bd\)
多次迭代,直到d = 1,可以得到以下柿子
\(\frac a{d_1d_2...d_k} a^{x-k} + \frac p{d_1d_2...d_k} y = \frac b{d_1d_2...d_k}\)
转化为原式 \(\frac a{d_1d_2...d_k} a^{x-k} \equiv \frac b{d_1d_2...d_k}\) \(mod (\frac p{d_1d_2...d_k})\)
记录一个变量r = \(\frac a{d_1d_2...d_k} a^{x-k}\),每次迭代时累乘上\(\frac a{d_i}\)
把r移向同余号右侧,那么我们就得到了一个标准的BSGS,但是同余运算中不能左右同除,于是我们用exgcd算出r关于\(\frac p{d_1d_2...d_k}\)的逆元,然后两边同乘以逆元,在跑一边BSGS即可
Code
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
typedef long long ll;
using namespace std;
inline int ksm(ll base,int pts,int mod)
{
ll ans = 1;
for(;pts > 0;pts >>= 1,base = 1ll * base * base % mod)
if(pts & 1)
ans = ans * base % mod;
return ans;
}
inline int BSGS(int a,ll b,int p)//a ^ x = b (% p)
{
__gnu_pbds::gp_hash_table <ll,int> q;
b %= p;
int t = ceil(sqrt(p));
for(int i = 0;i <= t;i++)
q[(ksm(a,i,p) * b % p)] = i;
ll c = ksm(a,t,p),now = 1;
for(int i = 1;i <= t;i++)
{
now = now * c % p;
if(q.find(now) != q.end())
{
int x = q[now];
return (i * t - x + p) % p;
}
}
return -1;
}
inline int exgcd(ll &x,int &y,int a,int b)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int ret = exgcd(x,y,b,a % b);
int k = y;
y = x - (a / b) * y;
x = k;
return ret;
}
inline int gcd(int a,int b)
{
if(b == 0) return a;
return gcd(b,a % b);
}
ll ot = 1;
inline int exBSGS(int a,int b,int p)
{
if(ot == b) return 0;
int x,y;
int d = gcd(a,p);
if(d == 1)
{
ll inv;
exgcd(inv,y,ot,p);
inv = ((inv % p) + p) % p;
return BSGS(a,(1ll * inv * b) % p,p);
}
if(b % d != 0) return -1;
ot = ot * (a / d) % (p / d);
int ret = exBSGS(a,b / d,p / d);
if(ret == -1) return -1;
return ret + 1;
}
signed main()
{
int a,p,b;
scanf("%d%d%d",&a,&p,&b);
while(a || p || b)
{
a %= p;b %= p;
if(b == 1 || p == 1)
{
puts("0");
scanf("%d%d%d",&a,&p,&b);
continue;
}
ot = 1;
int k = exBSGS(a,b,p);
if(k == -1)
printf("No Solution\n");
else
printf("%lld\n",k);
scanf("%d%d%d",&a,&p,&b);
}
return 0;
}
语法tip:
C++中有一种比map 和 unordered_map更快的hash映射gp_hash_table,用法和普通map相同
头文件
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
命名空间
using namespace __gnu_pbds
定义hash
(__gnu_pbds::)gp_hash_table <int,int> q;
2023.1.16[模板]BSGS/exBSGS的更多相关文章
- 算法笔记--BSGS && exBSGS 模板
https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...
- 【模板】exBSGS/Spoj3105 Mod
[模板]exBSGS/Spoj3105 Mod 题目描述 已知数\(a,p,b\),求满足\(a^x\equiv b \pmod p\)的最小自然数\(x\). 输入输出格式 输入格式: 每个测试文件 ...
- BSGS&EXBSGS 大手拉小手,大步小步走
大步小步走算法处理这样的问题: A^x = B (mod C) 求满足条件的最小的x(可能无解) 其中,A/B/C都可以是很大的数(long long以内) 先分类考虑一下: 当(A,C)==1 即A ...
- BSGS&ExBSGS
BSGS&ExBSGS 求解形如 \[a^x\equiv b\pmod p\] 的高次同余方程 BSGS 假装\(gcd(a,p)=1\). 设\(m=\lceil\sqrt p \rceil ...
- 模板BSGS(SDOI2011计算器) 模板EXBSGS
BSGS和EXBSGS是OI中用于解决A^xΞB(mod C)的常用算法. 1.BSGS BSGS用于A,C互质的情况. 令m=sqrt(C),此时x可表示为i*m+j. 式中i和j都<=sqr ...
- [note]BSGS & exBSGS
BSGS (感觉这东西还是要写一下) BSGS主要用于求解形如\(x^k=y\pmod p\)(注意这里p与x互质)这样的方程的最小正整数解的问题 设\(m=\lceil\sqrt p\rceil,k ...
- Luogu4195 【模板】exBSGS(exBSGS)
如果a和p互质,用扩欧求逆元就可以直接套用普通BSGS.考虑怎么将其化至这种情况. 注意到当x>=logp时gcd(ax,p)是一个定值,因为这样的话每个存在于a中的质因子,其在ax中的出现次数 ...
- LG4195 【模板】exBSGS
exBSGS 已知数\(a,p,b\),求满足\(a^x≡b\ (\bmod p)\)的最小自然数\(x\). \(100\%\)的数据,\(a,p,b≤10^9\). _皎月半洒花的题解 其实本质上 ...
- P4195 【模板】exBSGS/Spoj3105 Mod
传送门 首先要懂得 $BSGS$,$BSGS$ 可以求出关于 $Y$ 的方程 $X^Y \equiv Z (mod\ mo)$ 的最小解,其中 $gcd(X,Z)=1$ $exBSGS$ 算是 $BS ...
- BSGS && EXBSGS
基础BSGS 用处是什么呢w 大步小步发(Baby-Step-Giant-Step,简称BSGS),可以用来高效求解形如\(A^x≡B(mod C)\)(C为素数)的同余方程. 常用于求解离散对数问题 ...
随机推荐
- 介绍一个jmeter录制脚本谷歌插件 —— metersphere-chrome-plugin
该插件可将用户在浏览器操作时的 HTTP 请求记录下来并生成 JMX 文件(JMeter 脚本文件). 1. 插件解压 插件下载链接: https://pan.baidu.com/s/14nGb_s9 ...
- 秀++视频算法仓库-厂家对接规约V5
一.概要 (1)每个算法厂家在秀++云平台上会有一个厂商标识,譬如CS101:算法厂家可能有多个算法引擎,每个引擎有一个标识譬如Q101,引擎可以理解为一个可执行程序,可以同时分析多路算法:每个算法在 ...
- 状态机的技术选型,yyds!
前言 今天跟大家分享一个关于"状态机"的话题.状态属性在我们的现实生活中无处不在.比如电商场景会有一系列的订单状态(待支付.待发货.已发货.超时.关闭):员工提交请假申请会有申请状 ...
- 编码工具使用(go语言)
1.课程介绍 Git基础课程和实操 Goland介绍以及常用快捷键使用 Go delve 调试 你想要的linux 这里都有 2.版本控制工具介绍 原始的版本控制 修改文件,保存文件副本 版本控制的起 ...
- 【经验分享】配置用户通过Console口登录设备示例
组网需求 当用户无法进行远程登录设备时,可通过Console口进行本地登录.缺省情况下,使用Console用户界面登录设备时只需要密码认证.为了防止非法用户登录设备,修改Console用户界面的认证方 ...
- VS2019 iis无法在Web服务器上启动调试。打开的URL的IIS辅助进程当前没有运行
可以检查W3SVC服务与WAS这两个服务是否正在运行. 重启这两个服务就可以正常了
- Axios 类似于for循环发送批量请求{:axios.all axios.spread}。
Axios的请求都是异步的!不能用for循环遍历去批量发送请求 那如果我们需要类似与这样的请求怎么办呢 for(let i =0;i<array.length;i++){ axios.post( ...
- 持续发烧,聊聊Dart语言的静态编译,能挑战Go不?
前言 前两天写了几篇文章,谈了谈Dart做后端开发的优势,比如: <Dart开发服务端,我是不是发烧(骚)了?> <持续发烧,试试Dart语言的异步操作,效率提升500%> & ...
- Gradle 使用maven本地仓库 带来的思考
Gradle 使用maven本地仓库 带来的思考 本篇主要探究一下 在使用Gradle 的时候一般会配置 maven 的本地仓库的,那是不是Gradle 可以直接使用 maven本地仓库的jar呢 ? ...
- 利用python数据分析
利用python进行数据分析 本书由Python pandas项目创始人Wes McKinney亲笔撰写,详细介绍利用Python进行操作.处理.清洗和规整数据等方面的具体细节和基本要点.第2版针对P ...