[模板]大步小步算法——BSGS算法
大步小步算法用于解决:已知A, B, C,求X使得
A^x = B (mod C)
成立。
我们令x = im - j | m = ceil(sqrt(C)), i = [1, m], j = [0, m]
那么原式就变成了:
A^(im) = A^j * B
我们先枚举j,把A^j * B加入哈希表
然后枚举i,在表中查照A^(i*m),如果找到了,那么就找到了一个解。
算法的复杂度为O(n^0.5)
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll p, a, b, X1, t, T;
ll pow(ll a, ll b, ll p) {
ll ans = 1;
while(b) {
if(b & 1) ans = ans * a % p;
b >>= 1;
a = a * a % p;
}
return ans;
}
ll inv(ll a, ll p) {
return pow(a, p-2, p);
}
map<ll, ll> mp;
ll BSGS(ll A, ll B, ll C) {
mp.clear();
if(A % C == 0) return -2;
ll m = ceil(sqrt(C));
ll ans;
for(int i = 0; i <= m; i++) {
if(i == 0) {
ans = B % C;
mp[ans] = i;
continue;
}
ans = (ans * A) % C;
mp[ans] = i;
}
ll t = pow(A, m, C);
ans = t;
for(int i = 1; i <= m; i++) {
if(i != 1)ans = ans * t % C;
if(mp.count(ans)) {
int ret = i * m % C - mp[ans] % C;
return (ret % C + C)%C;
}
}
return -2;
}
int main() {
// freopen("input", "r", stdin);
scanf("%lld", &T);
while(T--) {
scanf("%lld %lld %lld %lld %lld", &p, &a, &b, &X1, &t);
if(X1 == t) {
printf("%d\n", 1);
continue;
}
if(a == 0) {
if(t == b) {
printf("%d\n", 2);
}
else printf("%d\n", -1);
continue;
}
if(a == 1) {
if(b == 0) {
printf("%d\n", -1);
continue;
}
ll ans = (((t-X1)%p + p)%p * inv(b, p)) % p;
printf("%lld\n", ans+1);
continue;
}
X1 %= p, a %= p, b %= p, t%= p;
ll tmp = (b%p * inv(a-1, p))%p;
ll B = ((t+tmp)%p * inv((X1+tmp) % p, p)) % p;
ll A = a;
ll ans = BSGS(A, B, p);
printf("%lld\n", ans+1);
}
return 0;
}
[模板]大步小步算法——BSGS算法的更多相关文章
- 【算法】BSGS算法
BSGS算法 BSGS算法用于求解关于x的模方程\(A^x\equiv B\mod P\)(P为质数),相当于求模意义下的对数. 思想: 由费马小定理,\(A^{p-1}\equiv 1\mod P\ ...
- 离散对数及其拓展 大步小步算法 BSGS
离散对数及其拓展 离散对数是在群Zp∗Z_{p}^{*}Zp∗而言的,其中ppp是素数.即在在群Zp∗Z_{p}^{*}Zp∗内,aaa是生成元,求关于xxx的方程ax=ba^x=bax=b的解, ...
- 大步小步算法模板题, poj2417
大步小步模板 (hash稍微有一点麻烦, poj不支持C++11略坑) #include <iostream> #include <vector> #include <c ...
- BSGS-Junior·大步小步算法
本文原载于:http://www.orchidany.cf/2019/02/06/BSGS-junior/#more \(\rm{0x01}\) \(\mathcal{Preface}\) \(\rm ...
- 离散对数&&大步小步算法及扩展
bsgs algorithm ax≡b(mod n) 大步小步算法,这个算法有一定的局限性,只有当gcd(a,m)=1时才可以用 原理 此处讨论n为素数的时候. ax≡b(mod n)(n为素数) 由 ...
- 【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 大水题一道 使用大步小步算法,把数字的运算换成矩阵的运算就好了 矩阵求逆?这么基础的线 ...
- BSGS算法(模板)
BSGS (大步小步算法) 已知\(a.b. c\),求\(x\).令\(a^x \equiv b \pmod c\). 步骤 \[m = \lceil \sqrtc\ \rceil \]\[x = ...
- uva11916 bsgs算法逆元模板,求逆元,组合计数
其实思维难度不是很大,但是各种处理很麻烦,公式推导到最后就是一个bsgs算法解方程 /* 要给M行N列的网格染色,其中有B个不用染色,其他每个格子涂一种颜色,同一列上下两个格子不能染相同的颜色 涂色方 ...
- BSGS算法(大小步算法)
$BSGS$ 算法 $Baby\ Steps\ Giant\ Steps$. 致力于解决给定两个互质的数 $a,\ p$ 求一个最小的非负整数 $x$ 使得 $a^x\equiv b(mod\ p)$ ...
随机推荐
- Multiplication Puzzle ZOJ - 1602
Multiplication Puzzle ZOJ - 1602 传送门 The multiplication puzzle is played with a row of cards, each c ...
- C++ 无符号整型和整型的区别
在Win 7系统中,short 表示的范围为 - 32767到 32767,而无符号的short表示的范围为0 到 65535,其他类型的同理可推导出来,当然,仅当数字不为负的时候才使用无符号类型. ...
- POJ:3190-Stall Reservations
传送门:http://poj.org/problem?id=3190 Stall Reservations Time Limit: 1000MS Memory Limit: 65536K Total ...
- [BZOJ2427][HAOI2010]软件安装(tarjan+树形DP)
如果依赖关系出现环,那么对于一个环里的点,要么都选要么都不选, 所以每个环可以当成一个点,也就是强连通分量 然后就可以构造出一颗树,然后树形背包瞎搞一下就行了 注意要搞一个虚拟节点当根节点 Code ...
- [Bzoj3991]寻宝游戏(dfs序+set)
Description 题目链接 Solution 用set按dfs序维护当前的宝物序列,那么答案为相邻2个点的距离加上头尾2个的距离 Code #include <cstdio> #in ...
- python-6面向对象编程
1-类和实例 class Student(object): def __init__(self, name, score):# _init__方法的第一个参数永远是self,表示创建的实例本身 sel ...
- 进入saftmode解决方案
Name node is in safe mode.The reported blocks 356 needs additional 2 blocks to reach the threshold 0 ...
- 2 semantic ui 框架的应用
为什么使用css框架 1.使用基础样式 : ui segment 分段:内容片段 <link rel="stylesheet" href="css/semanti ...
- hbase shell出现ERROR:Can't get master address from Zookeeper;znode data==null
hbase shell出现ERROR:Can't get master address from Zookeeper;znode data==null(ERROR:org.apache.hadoop. ...
- 初学JS——利用JS制作的别踩白块儿(街机模式) 小游戏
这个是上个星期5写的了,当时是突然想写个游戏,就想到了别踩白块儿,当时的想法是 可能普通模式的别踩白块儿因为他的“块儿”是滚动的向上这种,以我目前会的技术想不出怎么写, 但是如果是街机模式,通过你每按 ...