题目地址
解题思路
k == 1,求一步快速幂就可以了。
k == 2时,特判一下y是不是p的倍数,如果是则无解,否则就直接求以下逆元,因为p是素数。
k == 3时, 还是得先特判一下是不是倍数关系,是就无解,不是就直接套用北上广深算法。
AC代码
#include <iostream>
#include <cmath>
#include <map>
#include <cstdio>
using namespace std;
typedef long long ll;
ll qul(ll a, ll b, ll p)
{
ll sum = 1;
while (b)
{
if (b&1)
{
sum = sum*a%p;
}
a = a*a%p;
b>>=1;
}
return sum;
}
void slove(ll y, ll z, ll p)
{
map<ll, int> s;
if (y%p == 0)
{
printf("Orz, I cannot find x!\n");
return;
}
y%=p, z%=p;
if (z == 1)
{
printf("0\n");
}
else
{
int m = sqrt(p)+1;
ll t = z;
for (int i=0; i<=m; i++)
{
s[t] = i+1;
t = t*y%p;
}
ll q = qul(y, m, p);
t = 1;
bool flag = false;
for (int i=1; i<=m; i++)
{
t = t*q%p;
if (s[t])
{
printf("%d\n", i*m-s[t]+1);
flag = true;
break;
}
}
if (!flag)
printf("Orz, I cannot find x!\n");
}
}
int main()
{
int t, k;
while (~scanf("%d %d", &t, &k))
{
while (t--)
{
ll y, z, p;
scanf("%lld %lld %lld", &y, &z, &p);
if (k == 1)
{
printf("%lld\n", qul(y, z, p));
}
else if (k == 2)
{
if (y%p == 0&&z%p)
{
printf("Orz, I cannot find x!\n");
}
else
{
z%=p;
printf("%lld\n", qul(y, p-2, p)*z%p);
}
}
else if (k == 3)
{
slove(y, z, p);
}
}
}
return 0;
}