传送门
b
s
g
s
bsgs
bsgs基础题。
考虑到给的是原根,因此没无解的情况。
于是只需要每次把
a
,
b
a,b
a,b解出来。
然后可以通过预处理节省一部分时间。
代码:
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
typedef long long ll;
inline int ksm(int a,int p,int mod){int ret=1;for(;p;p>>=1,a=(ll)a*a%mod)if(p&1)ret=(ll)ret*a%mod;return ret;}
int g,p,sqr,inv;
tr1::unordered_map<int,int>S;
inline void init(int a,int mod){
sqr=ceil(sqrt(mod)),inv=ksm(a,mod-2,mod),a=ksm(a,sqr,mod);
for(ri i=0,mul=1;i<=mod/sqr;++i,mul=(ll)mul*a%mod)S[mul]=i?i:sqr;
}
inline int query(int b,int mod){for(ri i=0,mul=b;i<sqr;++i,mul=(ll)mul*inv%mod)if(S[mul])return (S[mul])%sqr*sqr+i;}
int main(){
int n,g,p;
g=read(),p=read(),init(g,p);
for(ri tt=read(),a,b;tt;--tt){
a=query(read()%p,p),b=query(read()%p,p);
cout<<ksm(ksm(g,a,p),b,p)<<'\n';
}
return 0;
}