# [BZOJ2242] 计算器 题解

Description

1、给定y,z,p,计算Y^Z Mod P 的值；
2、给定y,z,p，计算满足xy≡ Z ( mod P )的最小非负整数；
3、给定y,z,p，计算满足Y^x ≡ Z ( mod P)的最小非负整数。
Input

Output

Sample Input

【样例输入1】

3 1

2 1 3

2 2 3

2 3 3

【样例输入2】

3 2

2 1 3

2 2 3

2 3 3

【数据规模和约定】

Sample Output

【样例输出1】

2

1

2

【样例输出2】

2

1

0

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <map>
using namespace std;
#define rg register
#define LL long long
#define __space putchar(' ')
#define __endl putchar('\n')
#define debug printf("Time Test:%d\n",clock())
template <typename qwq> inline void read(qwq & x)
{
x = 0;
rg int f = 1;
rg char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
x *= f;
}
template <typename qaq> inline void print(qaq x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
int p;
inline LL Pow(LL x,LL y)
{
rg LL ret = 1;
while(y)
{
if (y & 1) ret = ret * x % p;
x = x * x % p;
y >>= 1;
}
return ret % p;
}
inline LL exgcd(LL a,LL b,LL & x,LL & y)
{
if (!b)
{
x = 1,y = 0;
return a;
}
rg LL temp = exgcd(b,a % b,x,y);
rg LL t = x;
x = y;
y = t - a / b * y;
return temp;
}
map<int,int> hash;
inline int Baby_Step_Giant_Step(int a,int b)
{
hash.clear();
b %= p;
rg int t = ceil(sqrt(p));
for (rg int j = 0; j < t; ++j)
{
rg int val = (LL) b * Pow(a,j) % p; //b * a ^ j;
hash[val] = j;
}
a = Pow(a,t); //a ^ t
if (!a) return !b ? 1 : -1;
for (rg int i = 0; i <= t; ++i)
{
rg int val = Pow(a,i); //(a ^ t) ^ i
rg int j = hash.find(val) == hash.end() ? -1 : hash[val];
if (j >= 0 && i * t - j >= 0) return i * t - j;
}
return -1;
}
int t,k,y,z;
LL xx,yy;
inline void work1()
{
print(Pow(y,z)),__endl;
return;
}
inline void work2()
{
rg LL gcd = exgcd(y,p,xx,yy);
if (z % gcd)
{
puts("Orz, I cannot find x!");
return;
}
rg LL temp = p / gcd;
while (xx < 0) xx += temp;
print(((xx * z / gcd) % temp + temp) % temp),__endl;
}
inline void work3()
{
rg LL ans = Baby_Step_Giant_Step(y,z);
if (ans == -1 ) puts("Orz, I cannot find x!");
else print(ans),__endl;
return;
}
int main()
{
while (t--)
{
switch (k)
{
case 1:
work1();
break;
case 2:
work2();
break;
case 3:
work3();
break;
}
}
return 0;
}

posted @ 2019-04-13 21:06  iPlayForSG  阅读(197)  评论(0编辑  收藏  举报