先把a求出来,然后求B^a,即可;
已知A ≡ g^a (mod P) ,求 a,
设a=i*m-j ===> A*(g^j) ≡ g^i(*m) (mod P);
枚举 i,j ==> i的范围 为0---> ceil(sqrt(P)); j的 范围 1----->ceii(sqrt(P));
先枚举j 将 A*(g^j)存到map里 mp[A*(g^j)]=j;
然后枚举i 寻找mp[g^(i*m)]不为0的第一个值,就是i的答案 ==》a=i*m-mp[g^(i*m)];
至于 i,j,的取值范围 详见:复制+粘贴
AC代码
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
using namespace std;
typedef long long LL;
map<LL,int>mp;
LL quc(LL a,LL b,LL mod)
{
LL res=1;
while (b)
{
if (b&1)
res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int main()
{
LL g,mod,a,b;
scanf("%lld%lld",&g,&mod);
int n;
LL v=ceil(sqrt(mod));
scanf("%d",&n);
while (n--)
{
scanf("%lld%lld",&a,&b);
mp.clear();
LL vv=a;
for (int j=0;j<=v;j++)
{
if (!j)
{
vv=a%mod;
mp[vv]=j;continue;
}
vv=vv*g%mod;
mp[vv]=j;
}
LL pp=quc(g,v,mod),ss=1;
LL re;
for (int i=1;i<=v;i++)
{
ss=ss*pp%mod;
if (mp[ss])
{
re=i*v-mp[ss];
re=(re%mod+mod)%mod;
break;
}
}
printf("%lld\n",quc(b,re,mod));
}
return 0;
}