bsgs演算法
bsgs演算法
bsgs演算法,又稱大小步演算法(某大神稱拔山蓋世演算法)。
主要用來解決
A^x=B(mod C)(C是質數),都是整數,已知A、B、C求x。(poj 2417 Discrete Logging)
具體步驟如下:
先把x=i*m-j,其中m=ceil(sqrt(C)),(ceil是向上取整)。
這樣原式就變為A^(i*m-j)=B(mod C),
再變為A^j×B=A^(m*i) (mod C)。
列舉j(範圍0-m),將A^j×B存入hash表
列舉i(範圍1-m),從hash表中尋找第一個滿足A^j×B=A^(m*i) (mod C)。
此時x=i*m-j即為所求。
在網上看到的其他題解大多用的是x=i*m+j,也可以做,只是會牽扯的求逆元,所以比較麻煩。使x=i*m-j就可以輕鬆避免這個問題了。
那麼肯定有人會有疑問為何只計算到m=ceil(sqrt(C))就可以確定答案呢?
x=i*m-j
也就是x 的最大值不會超過p,那超過p的怎麼辦 ?
有一個公式 a^(k mod p-1)=a^k (mod p) 這個公式的推導需要用到費馬小定理
k mod p-1可以看做 k-m(p-1) ,原式可化成 a^k/(a^(p-1))^m=a^k (mod p)
根據費馬小定理 a^(p-1)=1 (mod p) 其中p為質數 ,a,p 互質,可得a^k/1^m=a^k (mod p) a^k=a^k (mod p) 得證。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
long long a,b,c,m,f[10000000];
map<long long,int> mp;
long long qsm(long long x) //快速冪
{
long long sum=1; long long aa=a;
while (x>0)
{
if (x&1)
sum=(sum*aa)%c;
x=x>>1;
aa=(aa*aa)%c;
}
return sum;
}
int main()
{
mp.clear();
while (scanf("%lld%lld%lld",&c,&a,&b)!=EOF)
{
mp.clear();
if (a%c==0) //判斷a,c 是否互質,因為c 是質數,所以直接判斷是否整除即可
{
printf("no solution\n");
continue;
}
int p=false;
m=ceil(sqrt(c));
long long 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;
}
long long t=qsm(m); ans=1;
for (int i=1;i<=m;i++)
{
ans=(ans*t)%c;
if (mp[ans])
{
int t=i*m-mp[ans];
printf("%d\n",(t%c+c)%c);
p=true;
break;
}
}
if (!p)
printf("no solution\n");
}
}
相關文章
- BSGS與擴充套件BSGS套件
- 淺談BSGS和EXBSGS
- 擴充套件BSGS/exBSGS套件
- loj#2531. 「CQOI2018」破解 D-H 協議(BSGS)協議
- BZOJ3122: [Sdoi2013]隨機數生成器(BSGS)隨機
- 【演算法】KMP演算法演算法KMP
- 演算法-回溯演算法演算法
- 【JAVA演算法】圖論演算法 -- Dijkstra演算法Java演算法圖論
- 演算法(2)KMP演算法演算法KMP
- 【演算法】遞迴演算法演算法遞迴
- 演算法題:洗牌演算法演算法
- [演算法之回溯演算法]演算法
- Manacher演算法、KMP演算法演算法KMP
- 【演算法】KMP演算法解析演算法KMP
- 介面限流演算法:漏桶演算法&令牌桶演算法演算法
- 前端演算法:快速排序演算法前端演算法排序
- 演算法初探--遞迴演算法演算法遞迴
- BP演算法和LMBP演算法演算法
- 隨機演算法 概率演算法隨機演算法
- STL::演算法::常見演算法演算法
- 常用演算法 插值演算法演算法
- 前向分步演算法 && AdaBoost演算法 && 提升樹(GBDT)演算法 && XGBoost演算法演算法
- c/c++ 通用的(泛型)演算法 之 只讀演算法,寫演算法,排序演算法C++泛型演算法排序
- 介面限流演算法:漏桶演算法&令牌桶演算法&redis限流演算法Redis
- 什麼是演算法?如何學習演算法?演算法入門演算法
- 演算法金 | 突破最強演算法模型,決策樹演算法!!演算法模型
- 分類演算法-AdaBoot 演算法演算法boot
- 演算法(八):圖解KNN演算法演算法圖解KNN
- 演算法那些事之冒泡演算法演算法
- 基礎演算法之排序演算法演算法排序
- 最短路-SPFA演算法&Floyd演算法演算法
- 複習常用演算法_冒泡演算法演算法
- 常用演算法之貪心演算法演算法
- 演算法修養--A*尋路演算法演算法
- 演算法進階(8): EM演算法演算法
- 【JAVA演算法】排序演算法 -- 快速排序Java演算法排序
- 非對稱演算法----RSA演算法演算法
- 演算法篇---氣泡排序演算法演算法排序