第一问,快速幂
第二问,exgcd或
p是质数,所以y一定有逆元
x=y^(-1)*z
其中y^(-1)=y^(P-2)
因为0没有逆元,所以只有y=0时无解
第三问,BSGS
设x=bk+c
其中k=sqrt(P),b和c都小于sqrt(P)
Y^(bk+c)=Z
Y^(bk)=Z*Y^(-c)
用map记录一下Z*Y^(-c),一共sqrt(P)个数
枚举b,查询有没有对应的Z*Y^(-c),如果有,则更新答案
0要特判
第二问,exgcd或
p是质数,所以y一定有逆元
x=y^(-1)*z
其中y^(-1)=y^(P-2)
因为0没有逆元,所以只有y=0时无解
第三问,BSGS
设x=bk+c
其中k=sqrt(P),b和c都小于sqrt(P)
Y^(bk+c)=Z
Y^(bk)=Z*Y^(-c)
用map记录一下Z*Y^(-c),一共sqrt(P)个数
枚举b,查询有没有对应的Z*Y^(-c),如果有,则更新答案
0要特判
复杂度O(sqrt(P)*logP)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
int mod,y,z,k,T,n;
map<int,int> mp;
int power(int x,int y,int mod)
{
int ans=1;
while (y)
{
if (y&1) ans=(long long)ans*x%mod;
x=(long long)x*x%mod;
y>>=1;
}
return ans;
}
void BSGS(int y,int z,int mod)
{
if (y==0 && z==0) {printf("1\n");return;}
if (y==0 && z!=0) {printf("Orz, I cannot find x!\n");return;}
mp.clear();
int temp=1,p=power(y,mod-2,mod),k=ceil(sqrt(mod));
mp[z]=k+1;
for (int i=1;i<k;i++)
{
temp=(long long)temp*p%mod;
int t=(long long)temp*z%mod;
if (!mp[t]) mp[t]=i;
}
temp=1;p=power(y,k,mod);
for (int i=0;i<k;i++,temp=(long long)temp*p%mod)
{
if (mp[temp])
{
if (mp[temp]==k+1) printf("%d\n",i*k);
else printf("%d\n",i*k+mp[temp]);
return;
}
}
printf("Orz, I cannot find x!\n");
}
int main()
{
scanf("%d%d",&n,&T);
for (int i=1;i<=n;i++)
{
scanf("%d%d%d",&y,&z,&mod);
y%=mod;
if (T==1) printf("%d\n",power(y,z,mod));
else
if (T==2)
{
z%=mod;
if (y==0 && z!=0) printf("Orz, I cannot find x!\n");
else printf("%d\n",(long long)z*power(y,mod-2,mod)%mod);
}
else z%=mod,BSGS(y,z,mod);
}
return 0;
}