[51nod1038]X^A Mod P

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;
}

 

posted @ 2017-10-23 21:03  Elder_Giang  阅读(405)  评论(0编辑  收藏  举报