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
输入包含多组数据。
第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
以下行每行包含三个正整数y,z,p,描述一个询问。
Output
对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。
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
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
Hint
【数据规模和约定】
对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。
题解
数论三合一。
第一问,快速幂。
第二问,扩欧求特解。
第三问,BSGS。
1 //It is made by Awson on 2018.1.16 2 #include <set> 3 #include <map> 4 #include <cmath> 5 #include <ctime> 6 #include <queue> 7 #include <stack> 8 #include <cstdio> 9 #include <string> 10 #include <vector> 11 #include <cstdlib> 12 #include <cstring> 13 #include <iostream> 14 #include <algorithm> 15 #define LL long long 16 #define Abs(a) ((a) < 0 ? (-(a)) : (a)) 17 #define Max(a, b) ((a) > (b) ? (a) : (b)) 18 #define Min(a, b) ((a) < (b) ? (a) : (b)) 19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b)) 20 using namespace std; 21 const LL MOD = 233333; 22 void read(LL &x) { 23 char ch; bool flag = 0; 24 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar()); 25 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar()); 26 x *= 1-2*flag; 27 } 28 void write(LL x) { 29 if (x > 9) write(x/10); 30 putchar(x%10+48); 31 } 32 33 LL t, l, a, b, c; 34 35 map<LL, int>mp; 36 LL exgcd(LL a, LL b, LL &x, LL &y) { 37 if (b == 0) {x = 1, y = 0; return a; } 38 LL d = exgcd(b, a%b, x, y), t = x; 39 x = y, y = t-a/b*y; 40 return d; 41 } 42 LL quick_pow(LL a, LL b, LL c) { 43 LL ans = 1; 44 while (b) { 45 if (b&1) ans = ans*a%c; 46 a = a*a%c, b >>= 1; 47 } 48 return ans; 49 } 50 51 LL BSGS(LL a, LL b, LL c) { 52 if (b == 1) return 0; 53 if (a == 0 && b != 0) return -1; 54 mp.clear(); 55 LL tim = ceil(sqrt(c)), tmp = b%c; 56 for (int i = 0; i <= tim; i++) { 57 mp[tmp] = i, tmp = tmp*a%c; 58 } 59 LL t = tmp = quick_pow(a, tim, c); 60 for (int i = 1; i <= tim; i++) { 61 if (mp.count(tmp)) return tim*i-mp[tmp]; 62 tmp = tmp*t%c; 63 } 64 return -1; 65 } 66 void work() { 67 read(t), read(l); 68 while (t--) { 69 read(a), read(b), read(c); 70 if (l == 1) write(quick_pow(a, b, c)), putchar(' '); 71 else if (l == 2) { 72 LL x, y; LL d = exgcd(a, c, x, y); 73 if (b%d) printf("Orz, I cannot find x! "); 74 else {x = x*b/d, d = c/d; write((x%d+d)%d), putchar(' '); } 75 }else { 76 LL ans = BSGS(a%c, b%c, c); 77 if (ans == -1) printf("Orz, I cannot find x! "); 78 else write(ans), putchar(' '); 79 } 80 } 81 } 82 int main() { 83 work(); 84 return 0; 85 }