【模板】exBSGS

【模板】exBSGS(luogu)

Solution

$$a^{x} \equiv b\pmod{p}$$
$$a^{x}+k \ast p =b$$
设d为gcd(a,p)
$$\frac{a^x}{d}+\frac{k \ast p}{d}=\frac{b}{d}$$
可以看出若b不能被d整除则无解
$$\frac{a^k}{d} \ast a^{x-k} \equiv \frac{b}{d}\pmod{\frac{p}{d}}$$
这样直到p/d为质数即可用普通BSGS算法求解

Code

#include <cstdio>
#include <cstdlib>
#include <map>
#include <cmath>
#define ll long long
using namespace std;
map <ll,int> ha;
ll a,b,p,x;
int k;
ll gcd(ll a,ll b)
{
    if(!b) return a;
    return gcd(b,a%b);
}
ll qpow(ll x,ll y,ll p)
{
    ll an=1;
    while(y)
    {
        if(y&1) an=an*x%p;
        x=x*x%p,y>>=1;
    }
    return an%p;
}
void solve(ll a,ll b,ll p)
{
    a%=p,b%=p;
    x=1,k=0;
    while(1)
    {
        ll d=gcd(a,p);
        if(d==1) break;
        if(b%d){puts("No Solution");return ;}
        b/=d,p/=d,k++,x=(x*a/d)%p;
        if(b==x){printf("%d\n",k);return ;}
    }
    ll y=sqrt(p);
    ha.clear();
    for(ll i=0,t=b;i<y;i++,t=t*a%p) ha[t]=i+1;
    ll t=qpow(a,y,p),now=x*t%p;
    for(ll i=1;i<=y;i++,now=now*t%p)
        if(ha.count(now)){printf("%lld\n",i*y-ha[now]+1+k);return;}
    puts("No Solution");
}
int main()
{
    while(scanf("%lld%lld%lld",&a,&p,&b) && a+b+p>0) solve(a,b,p);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hsez-cyx/p/12520369.html
今日推荐