HDU---2815:Mod Tree【扩展BSGS模板】

题意:

a^x\equiv n~(mod~p),解最小X满足同余式

分析:

扩展BSGS算法:

这时a,p不一定互质,先祭上初等数论的模公式:

ax\equiv n~(mod~p)\Rightarrow \frac{a}{d}x\equiv \frac{n}{d}~(mod~ \frac{p}{d})~~~(d=gcd(a,p))

于是我们可以一直提出gcd(a,p),直到二者互质,假设经过t次后二者互质:

\frac{a^t}{v}*a^{x-t}\equiv \frac{n}{v}~(mod~\frac{p}{v})

如果n 除不尽 v ,则无解,否则换元,x = x - t,n = n/v,p = p/c,a^t/v 放两边都行,带入BSGS求最小解为:i * m - j + t

但是最小解也有可能在[1,t]中,所以在提公因子时必须特判 a^t/v == n/v (mod p)?

代码:

#include 

using namespace std;
typedef long long ll;
ll a,n,p;
ll qpow(ll a,ll x)
{
    ll res = 1;
    while(x){
        if(x&1) res = res * a % p;
        a = a * a % p;
        x >>= 1;
    }
    return res % p;
}
int exbsgs()
{
    ll g = __gcd(a,p);
    ll step = 0,b = 1;
    while(g != 1){
        if(n%g) return -1;
        n /= g; p /= g; step++;
        b = b*(a/g) % p;
        g = __gcd(a,p);
        if(n == b) return step;
    }
    map mp;
    int k = ceil(sqrt(p*1.0));
    ll v = n;
    for(int j = 1; j <= k ;++j){
        v = v * a % p;
        mp[v] = j;
    }
    v = qpow(a,k);
    ll vv = b;
    for(int i = 1; i <= k+1; ++i){
        vv = vv * v % p;
        if(mp[vv]) return i * k - mp[vv] + step;
    }
    return -1;
}
int main()
{
    while(cin>>a>>p>>n){
        if(n>=p) {cout<<"Orz,I can’t find D!"<

 

你可能感兴趣的:(数论大家庭,模板)