Description
Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 2 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that
BL == N (mod P)
for each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print “no solution”.
Solution
原来这玩意叫离散对数啊
求AB≡C(modP)AB≡C(modP)这样的东西直接上BSGS
Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <map>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
std:: map <int, int> map;
LL ksm(LL x,LL dep,LL p) {
if (dep==0) return 1;
if (dep==1) return x%p;
LL tmp=ksm(x,dep/2,p);
if (dep&1) return tmp*tmp%p*x%p;
return tmp*tmp%p;
}
void BSGS(LL b,LL n,LL p) {
map.clear();
int t=(int)ceil(sqrt(p));
rep(i,0,t) {
LL tmp=ksm(b,i,p)*n%p;
map[tmp]=i;
}
rep(i,1,t) {
LL tmp=ksm(b,t*i,p);
if (map.count(tmp)) {
LL ans=t*i-map[tmp];
while (ans<0) ans+=p;
printf("%lld\n", ans);
return ;
}
}
puts("no solution");
}
int main(void) {
LL b,n,p;
while (~scanf("%lld%lld%lld",&p,&b,&n)) {
BSGS(b,n,p);
}
return 0;
}