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为素数)的同余方程. 常用于求解离散对数问题 ...
随机推荐
- webpack优化项目
在使用vue 构建项目的时候 ,会用到vue.js, vue-router.js, 等库,通常打包的话会将这些公用的代码打包的一个文件中,导致该文件过大影响加载的速度.那么可以考虑使用cdn 加速的方 ...
- vue 数组更新(push【可用】,$set,slice,filter,map【都属于浅拷贝】)问题
this.$axios.post('https://....php',this.$qs.stringify({ user: 'suess' })) .then(res => { this.dat ...
- bootstrap-table参数
table.bootstrapTable({ url:'/Home/geurl', //请求后台的URL(*) method:'get', //请求方式(*) toolbar:'#toolbar', ...
- DevOps 必备的 Kubernetes 安全清单
Kubernetes 是当今许多公司采用的容器编排平台,它的实施需要对其生态系统有一定的了解,以便部署一个准备好用于生产的集群.然而从原则上来说,Kubernetes 并不是一个安全的平台,因为它缺乏 ...
- go mod常用命令 已经 常见问题
最近接触到go mod,网上查了查资料,这里记录一下. 1 介绍 1.1.go mod是什么 go mod 是Golang 1.11 版本引入的官方包(package)依赖管理工具,用于解决之前没有地 ...
- C++期末考试题库
哈尔滨商业大学计算机专业C++期末考试题库 下载:题库 示例: 一.单选题:1.能作为 C ++程序的基本单位是( C )A .字符 B .语句 C .函数 D .源程序文件2.程序中主函数的名字为( ...
- Sql Server日期转汉字字符串
以下脚本转至互联网,增加了自己需要的功能并改成了函数的方式 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ================== ...
- tostring、(string)和 String.valueOf()
上周遇到一个问题,只怪自己平时没注意这个细节,从数据库取数据在map集合里,取出该值是我用了.tostring的方法,一次在当取出数据为空时代码报java.lang.NullPointerExcept ...
- Golang反射获得变量类型和值
1. 什么是反射 反射是程序在运行期间获取变量的类型和值.或者执行变量的方法的能力. Golang反射包中有两对非常重要的函数和类型,两个函数分别是: reflect.TypeOf 能获取类型信息re ...
- 【kafka】JDBC connector进行表数据增量同步过程中的源表与目标表时间不一致问题解决
〇.参考资料 一.现象 1.Oracle源表数据 2.PG同步后的表数据 3.现象 时间不一致,差了8个小时 4.查看对应的connector信息 (1)source { "connecto ...