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为素数)的同余方程. 常用于求解离散对数问题 ...
随机推荐
- 部署redis
1. 下载redis 下载地址:https://redis.io/download/ 下载版本:6.2.7 应用包:redis-6.2.7.tar.gz 2. 上传服务器并解压 将redis安装包上传 ...
- Spring Boot 中使用 tkMapper
说明:基于 MyBatis 有很多第三方功能插件,这些插件可以完成数据操作方法的封装.数据库逆向工程的生成等. tkMapper 和 MyBatis-plus 都是基于 MyBatis 提供的第三方插 ...
- JUC学习笔记——共享模型之管程
JUC学习笔记--共享模型之管程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的管程部分 我们会分为以下几部分进行介绍: 共享问题 共享问题解决方案 线程安全分析 Monitor ...
- MongoDB 数据库的学习
一.MongoDB的简介 1.MongoDB是什么? MongoDB 是由 C++ 语言编写的,基于分布式文件存储的数据库,是一个介于关系数据库和非关系数据库之间的产品,是最接近于关系型数据库的 No ...
- Java:String、StringBuilder、StringJoiner学习笔记
String创建的俩种方式 1.直接赋值 String str = "Hello World!"; 当使用直接赋值的方式去创建字符串的时候,虚拟机会去串池里去检查字符串是否存在,如 ...
- hwlog---huawei.com/npu-exporter/utils---utils.go
// Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.// Package utils offer the so ...
- Spring Cloud Circuit Breaker 使用示例
Spring Cloud Circuit Breaker 使用示例 作者: Grey 原文地址: 博客园:Spring Cloud Circuit Breaker 使用示例 CSDN:Spring C ...
- openssh编译rpm包(防火防盗防漏扫)
参考链接:https://www.jianshu.com/p/0882b0502960 openssh下载链接: wget https://cdn.openbsd.org/pub/OpenBSD/Op ...
- centos8安装vsftpd
注:ftp只能走相对路径传输文件,需要先cd到文件路径,然后ftp登陆,put上传,get下载 1. 装包与卸载 yum -y install vsftpd yum -y autoremove vsf ...
- vivo大数据日志采集Agent设计实践
作者:vivo 互联网存储技术团队- Qiu Sidi 在企业大数据体系建设过程中,数据采集是其中的首要环节.然而,当前行业内的相关开源数据采集组件,并无法满足企业大规模数据采集的需求与有效的数据采集 ...