BSGS
给定一个质数 p,以及一个整数 a,一个整数 b,现在要求你计算一个最小的非负整数 x,满足,若找不到则返回-1。(BSGS需满足a与p互质)
ll bsgs(ll a,ll b,ll m){
static unordered_map<ll,ll> mp;
mp.clear();
ll cur=1,t=sqrt(m)+1;
for(int B=1;B<=t;B++){
cur=cur*a%m;
mp[b*cur%m]=B;
}
ll now=cur;
for(int A=1;A<=t;A++){
auto it = mp.find(now);
if(it!=mp.end()) return 1ll*A*t-it->second;
now=now*cur%m;
}
return -1;
}
ex_BSGS
给定 a,p,b,求满足 的最小自然数 x,若找不到,则返回负无穷。(ex_BSGS无需互质)
ll gcd(ll a,ll b){
return (b==0)?a:gcd(b,a%b);
}
ll bsgs(ll a,ll b,ll m,ll k=1){
static unordered_map<ll,ll> mp;
mp.clear();
ll cur=1,t=sqrt(m)+1;
for(int B=1;B<=t;B++){
cur=cur*a%m;
mp[b*cur%m]=B;
}
ll now=cur*k%m;
for(int A=1;A<=t;A++){
auto it=mp.find(now);
if(it!=mp.end()) return 1ll*A*t-it->second;
now=now*cur%m;
}
return -0x3f3f3f3f;
}
ll ex_bsgs(ll a,ll b,ll m,ll k=1){
ll A=a%m,B=b%m,M=m;
if(b==1) return 0;
ll cur=1%m;
for(int i=0;;i++){
if(cur==B) return i;
cur=cur*A%M;
ll d=gcd(a,m);
if(b%d) return -0x3f3f3f3f;
if(d==1) return bsgs(a,b,m,k*a%m)+i+1;
k=k*a/d%m;
b/=d;
m/=d;
}
}