BSGS&exBSGS
一、BSGS
1. 简介
即baby(boy) step giant(girl) step算法,用于处理
本质上有一点点像二分搜索的意味在里面
2. 算法流程
有
令
我们可以把所有的 hash
/map
/unordered_map
)上
枚举
3. 时间复杂度
显然地,复杂度为
如果使用 map
/unordered_map
则为
注:建议做 UVA10225,洛谷 P3846 数据有亿点水
4. 警戒点
一定要上取整 ,i 从0->n! ,i 从1->n!
5. 代码
typedef long long ll; map<ll,ll> Map; ll BSGS(ll a,ll b,ll p){ Map.clear(); ll t = ceil(sqrt(p));//必须加上ceil ll k = 1; Map[b%p] = 0; for(ll i = 1; i <= t; ++i)Map[(k = k * a % p) * b % p] = i;//计算b*a^i a = 1; for(ll i = 1; i <= t; ++i){ a = a * k % p; if(Map.count(a))//在映射数组中找a^i return i*t-Map[a]; } return -1; } int main(){ ll p,b,n,ans; while(~scanf("%lld%lld%lld",&p,&b,&n)) if((ans = BSGS(b,n,p)) != -1)printf("%lld\n",ans); else puts("no solution"); return 0; }
二、exBSGS
1. 简介
exBSGS
2. 算法实现
此时
左右同除
特别的,当
就可以转化为
继续递归,直到 BSGS
即可
3. 警戒点
(1) 为了节省时间,我们将每次的
hack数据:a = 18 b = 16 p = 14 ans = 2
(2) 计算累乘时应该对下一轮的
(3) 我们要在递归前对
(4) 初始时
hack数据:a = 18 b = 49 p = 48 ans = 0
(5) 计算逆元的时候需要使用 exgcd
而不是 快速幂
因为
4. 代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; map<ll,ll> Map; ll BSGS(ll a,ll b,ll p){ Map.clear(); ll t = ceil(sqrt(p)); ll k = 1; Map[b%p] = 0; for(ll i = 1; i <= t; ++i)Map[(k = k * a % p) * b % p] = i; a = 1; for(ll i = 1; i <= t; ++i){ a = a * k % p; if(Map.count(a)) return i*t-Map[a]; } return -1; } ll exgcd(ll a,ll b,ll &x,ll &y){ if(!b){x = 1;y = 0;return a;} ll d = exgcd(b,a%b,x,y); ll t = x; x = y; y = t - (a/b) * y; return d; } ll inv(ll a,ll b){ ll x,y; exgcd(a,b,x,y); return (x % b + b) % b; } ll gcd(ll x,ll y){return y ? gcd(y,x%y) : x;} ll x = 1;//即上面说的k ll exBSGS(ll a,ll b,ll p){ ll d = gcd(a,p); if(b == x)return 0;//相等判定 if(d == 1){ return BSGS(a,b*inv(x,p) % p,p);//使用exgcd } if(b % d != 0)return -1; else{ x = a/d * x % (p/d); ll res = exBSGS(a,b/d,p/d); if(res == -1)return -1; return res + 1; } } ll a,p,b; int main(){ while(~scanf("%lld%lld%lld",&a,&p,&b)){ x = 1; if(a == 0 && b == 0 && p == 0)break; a%=p;b%=p; if(b==1||p==1){ puts("0");continue;//递归之前判定 } ll res = exBSGS(a%p,b%p,p); if(res == -1)puts("No Solution"); else printf("%lld\n",res); } }
本文来自博客园,作者:ricky_lin,转载请注明原文链接:https://www.cnblogs.com/rickylin/p/17054359.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步