X^A mod P = B,其中P为质数。给出P和A B,求< P的所有X。
例如:P = 11,A = 3,B = 5。
3^3 Mod 11 = 5
所有数据中,解的数量不超过Sqrt(P)。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100)
第2 - T + 1行:每行3个数P A B,中间用空格隔开。(1 <= A, B < P <= 10^9, P为质数)
Output
共T行,每行包括符合条件的X,且0 <= X < P,如果有多个,按照升序排列,中间用空格隔开。如果没有符合条件的X,输出:No Solution。所有数据中,解的数量不超过Sqrt(P)。Input示例
3
11 3 5
13 3 1
13 2 2
Output示例
3
1 3 9
No Solution
http://blog.csdn.net/qq_27599517/article/details/52914733
#pragma GCC optimize("O2") #include <cmath> #include <cstdio> #include <vector> #include <algorithm> using namespace std; typedef long long LL; inline LL quick_power(LL a, LL b, const LL &mod){ LL s = 1; while(b){ if(b & 1) s = s * a % mod; b >>= 1; a = a * a % mod; } return s; } LL ex_gcd(LL a, LL b, LL &x, LL &y){ if(!b){ x = 1; y = 0; return a; } else{ LL gcd = ex_gcd(b, a % b, y, x); y -= a / b * x; return gcd; } } vector<LL> pri; inline bool Judge_g(const LL &g, const LL &P){ int size = pri.size(); for(int i = 0; i < size; i++) if(quick_power(g, (P - 1) / pri[i], P) == 1) return false; return true; } inline LL primitive_root(const LL &P){ LL t = P - 1; for(int i = 2; i * i <= t; i++){ if(t % i == 0){ pri.push_back(i); while(t % i == 0) t /= i; } } if(t != 1) pri.push_back(t); LL g = 2; while(true){ if(Judge_g(g, P)) return g; g++; } } struct Node{ LL val; int id; bool operator < (const Node &rhs) const { return val == rhs.val ? id < rhs.id : val < rhs.val; } }arr[100000], tp; inline LL discerte_log(const LL &A, const LL &B, const LL &P){ LL s = ceil(sqrt(P)); LL cur = 1; for(int i = 0; i < s; i++){ arr[i].id = i; arr[i].val = cur; cur = cur * A % P; } sort(arr, arr + s); LL inv = quick_power(cur, P - 2, P); cur = 1; for(int t, i = 0; i < s; i++){ tp.val = cur * B % P; tp.id = -1; t = lower_bound(arr, arr + s, tp) - arr; if(arr[t].val == tp.val) return i * s + arr[t].id; cur = cur * inv % P; } return -1; } inline void work(vector<LL> &ans, const LL &P, const LL &A, const LL &B){ if(B == 0){ ans.push_back(0); return; } LL g = primitive_root(P), m = discerte_log(g, B, P); if(m == -1) return; LL x, y, gcd = ex_gcd(A, P - 1, x, y); if(m % gcd) return; x = x * (m / gcd) % (P - 1); LL delta = (P - 1) / gcd; for(int i = 0; i < gcd; i++){ x = ((x + delta) % (P - 1) + (P - 1)) % (P - 1); ans.push_back(quick_power(g, x, P)); } sort(ans.begin(), ans.end()); ans.erase(unique(ans.begin(), ans.end()), ans.end()); } vector<LL> ans; int main(){ int T; scanf("%d", &T); while(T--){ LL P, A, B; scanf("%lld %lld %lld", &P, &A, &B); ans.clear(); work(ans, P, A, B); if(ans.empty()) puts("No Solution"); else{ int size = ans.size(); for(int i = 0; i < size; i++) printf("%lld ", ans[i]); puts(""); } } return 0; }