Summary of bsgs algorithm
Beijing-Shanghai-Guangzhou-Shenzhen Algorithm
BS High God Algorithm
Now to solve the equation about \(x\) \(y^x\equiv z\ (\mod p\ )\)
Then \(\gcd(y,p)=1\)
Write \(x\) in the form of \(x=am-b\)
\(y^{am}\equiv z\times y^b\ (\mod p\ )\)
The value of \(b\) is only \([0,m)\) , and then the result of each value can be calculated and stored in a hash table
Then enumerate the left side \(a\) equality, complexity \(O(\max(m,p/m))\)
Obviously, taking \(m=\sqrt p\) is the best
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<map>
#include<cmath>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
ll y,z,p;
il ll pow(ll x,ll y){
ll ret=1;
while(y){
if(y&1)ret=ret*x%p;
x=x*x%p;y>>=1;
}return ret;
}
il ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
std::map<ll,ll>yyb;
int main(){
#ifdef xzz
freopen("calc.in","r",stdin);
freopen("calc.out","w",stdout);
#endif
int T=gi(),k=gi();
while(T--){
y=gi(),z=gi(),p=gi();
if(k==1)printf("%lld\n",pow(y,z));
else if(k==2){
z%=p;
ll d=(y%p)?1:p;
if(z%d){puts("Orz, I cannot find x!");goto facai;}
else printf("%lld\n",z*pow(y,p-2)%p);
}else{
if(y%p){
y%=p,z%=p;
if(z==1)
if(y==0){puts("Orz, I cannot find x!");goto facai;}
else{puts("0");goto facai;}
ll m=sqrt(p)+1;yyb.clear();
for(rg ll i=0,x=z%p;i<m;++i,x=x*y%p)yyb[x]=i;
for(rg ll i=1,x=pow(y,m),t=x;i<=m+1;++i,t=t*x%p){
if(yyb.find(t)==yyb.end())continue;
printf("%lld\n",i*m-yyb[t]);
goto facai;
}
puts("Orz, I cannot find x!");
}else puts("Orz, I cannot find x!");
facai:;
}
}
return 0;
}
There is also a tiankeng extension BSGS
to be filled