poj 2417 Discrete Logging

题面
bsgs模板。
大意是给三个数a,b,p,p是质数,求出x满足a^x=b(mod p)
变个形 设x=i*m-j
a^(i*m-j)=b(mod p)
a^(i*m)=b*a^j (mod p)
m为ceil(sqrt(p))
我们就先枚举j算出b*a^j,做一份hash表,用map存。
之后再枚举i,看表中是否有a^(i*m)。
j是0~m,i是1~m。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#define LL long long

using namespace std;

LL a,m,b,p,now;
map<LL,LL> mp;

inline LL fast_pow(LL a,LL b){
    LL ret=1;
    LL aa=a;
    for(;b;b>>=1){
        if(b&1) ret=(ret*aa)%p; 
        aa=aa*aa%p;
    }
    return ret;
}

int main(){
    while(~scanf("%lld%lld%lld",&p,&a,&b)){
        if(a%p==0){
            puts("no solution");
            continue;
        }
        mp.clear();
        now=b%p;
        bool flag=false;
        mp[now]=0;
        m=ceil(sqrt(p));
        for(register int i=1;i<=m;i++){
            now=(now*a)%p;
            mp[now]=i;
        }
        now=1;
        LL k=fast_pow(a,m);
        for(register int i=1;i<=m;i++){
            now=now*k%p;
            if(mp[now]){
                LL ans=i*m-mp[now];
                printf("%lld
",(ans%p+p)%p);
                flag=true;
                break;
            }
        }
        if(!flag) puts("no solution");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/sdfzsyq/p/9677005.html