题意:(题意好像很明显)
思路:第一种ksm,第二种欧几里得拓展,第三种bsgs(其实就是模板题,然而第一次写bsgs)
代码:
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
map<ll,ll> mp;
ll read()
{
ll x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
ll s=ch-48;
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-48;
return s*x;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if (b==0)
{
x=1,y=0;
return a;
}
ll tmp=exgcd(b,a%b,y,x);
y-=a/b*x;
return tmp;
}
ll ksm(ll y,ll z,ll p)
{
y%=p;
ll now=1;
for (ll i=z;i;i>>=1,y=(ll)y*y%p)
if (i&1) now=(ll)now*y%p;
return now;
}
int main()
{
ll T=read(),k=read();
while (T--)
{
ll y=read(),z=read(),p=read();
if (k==1) printf("%lld\n",ksm(y,z,p));
if (k==2)
{
ll X,Y;
ll temp=exgcd(y,p,X,Y);
if (z%temp) puts("Orz, I cannot find x!");
else
{
z/=temp,p/=temp,y/=temp;
exgcd(y,p,X,Y);
X=((ll)X*z%p+p)%p;
printf("%lld\n",X);
}
}
if (k==3)
{
y%=p;
if (!y&&!z)
{
puts("1");
continue;
}
if (!y)
{
puts("Orz, I cannot find x!");
continue;
}
mp.clear();
ll m=ceil(sqrt(p)),now=z;
for (ll i=0;i<=m;i++,now=now*y%p)
if (!mp[now]) mp[now]=i;
ll b=1,c=ksm(y,m,p),ans=-1;
for (ll i=0;i<=m;i++,b=(b*c)%p)
if (mp.count(b))
{
printf("%lld\n",ans=(i*m-mp[b]));
break;
}
if (ans==-1) puts("Orz, I cannot find x!");
}
}
return 0;
}