【模板】BSGS
作者:互联网
给你\(a,b,p\in \mathbb{N}_+\),请解出方程\(a^x\equiv b\pmod p\)的最小解\(x\in\mathbb{N}_+\)。
#include <stdio.h>
#include <map>
#define ull unsigned long long
#define ll long long
ll light_multi(ll _a,ll _b,ll _p) {
_a %= _p, _b %= _p;
ull _c = (long double)_a*_b/_p;
ull _x = _a*_b, _y = _c*_p;
ll _res = (ll)(_x%_p)-(ll)(_y%_p);
if(_res < 0) _res += _p;
return _res;
}
ll defended_pow(ll _a,ll _n,ll _p) {
ll _res = 1;
while(_n) {
if(_n&1) _res = light_multi(_res,_a,_p);
_a = light_multi(_a,_a,_p);
_n >>= 1;
}
return _res;
}
float InvSqrt(float x) {
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f375a86-(i>>1);
x = *(float*)&i;
x = x*(1.5f-xhalf*x*x);
x = x*(1.5f-xhalf*x*x);
x = x*(1.5f-xhalf*x*x);
return x;
}
std :: map<ll,ll> hash;
ll BSGS(ll a,ll b,ll p) {
b %= p;
ll t = (ll)(1.0/InvSqrt(p))+1;
for(ll i = 0;i < t;++i)
hash[b*defended_pow(a,i,p)%p] = i;
a = defended_pow(a,t,p);//ATP www ;
if(!a) return b == 0 ? 1 : -1;
for(ll i = 1;i <= t;++i) {
ll tmp = defended_pow(a,i,p);
int j = (hash.find(tmp) == hash.end()) ? -1 : hash[tmp];
if(j >= 0&&i*t-j >= 0)
return i*t-j;
}
return -1;
}
ll a, b, p;
signed main() {
scanf("%lld %lld %lld",&p,&a,&b);
ll ans = BSGS(a,b,p);
if(ans == -1)
printf("no solution");
else
printf("%lld",ans);
}
标签:return,res,ll,float,long,lld,模板,BSGS 来源: https://www.cnblogs.com/bikuhiku/p/BSGS.html