SGU 261. Discrete Roots

给定(p, k, A),满足(k, p)是质数,求

[x^k equiv A mod p]

不会。。。

upd:3:29

两边取指标,是求

[k ext{ind}_xequiv ext{ind}_Amod p-1]

的解数,先求最小的解,然后暴力求之后的就行了。

 1 #include <iostream>
 2 #include <map>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <vector>
 7 #include <cmath>
 8 using namespace std;
 9 typedef long long LL;
10 
11 vector<LL> f, as;
12 LL fast_pow(LL base, LL index, LL mod) {
13     LL ret = 1;
14     for(; index; index >>= 1, base = base * base % mod)
15         if(index & 1) ret = ret * base % mod;
16     return ret;
17 }
18 bool test_Primitive_Root(LL g, LL p) {
19     for(LL i = 0; i < f.size(); ++i)
20         if(fast_pow(g, (p - 1) / f[i], p) == 1)
21             return 0;
22     return 1;
23 }
24 LL get_Primitive_Root(LL p) {
25     f.clear();
26     LL tmp = p - 1;
27     for(LL i = 2; i <= tmp / i; ++i) 
28         if(tmp % i == 0)
29             for(f.push_back(i); tmp % i == 0; tmp /= i);
30     if(tmp != 1) f.push_back(tmp);
31     for(LL g = 1; ; ++g) {
32         if(test_Primitive_Root(g, p))
33             return g;
34     }
35 }
36 LL get_Discrete_Logarithm(LL x, LL n, LL m) {
37     map<LL, int> rec;
38     LL s = (LL)(sqrt((double)m) + 0.5), cur = 1;
39     for(LL i = 0; i < s; rec[cur] = i, cur = cur * x % m, ++i);
40     LL mul = cur;
41     cur = 1;
42     for(LL i = 0; i < s; ++i) {
43         LL more = n * fast_pow(cur, m - 2, m) % m;
44         if(rec.count(more))
45             return i * s + rec[more];
46         cur = cur * mul % m;
47     }
48     return -1;
49 }
50 LL ext_Euclid(LL a, LL b, LL &x, LL &y) {
51     if(b == 0) {
52         x = 1, y = 0;
53         return a;
54     } else {
55         LL ret = ext_Euclid(b, a % b, y, x);
56         y -= x * (a / b);
57         return ret;
58     }
59 }
60 void solve_Linear_Mod_Equation(LL a, LL b, LL n) {
61     LL x, y, d;
62     as.clear();
63     d = ext_Euclid(a, n, x, y);
64     if(b % d == 0) {
65         x %= n, x += n, x %= n;
66         as.push_back(x * (b / d) % (n / d));
67         for(LL i = 1; i < d; ++i)
68             as.push_back((as[0] + i * n / d) % n);
69     }
70 }
71 
72 int main() {
73 #ifndef ONLINE_JUDGE
74     freopen("data.in", "r", stdin); freopen("data.out", "w", stdout);
75 #endif
76 
77     LL p, k, a;
78     cin >> p >> k >> a;
79     if(a == 0) {
80         puts("1
0");
81         return 0;
82     }
83     LL g = get_Primitive_Root(p);
84     LL q = get_Discrete_Logarithm(g, a, p);
85     solve_Linear_Mod_Equation(k, q, p - 1);
86     for(int i = 0; i < as.size(); ++i)
87         as[i] = fast_pow(g, as[i], p);
88     sort(as.begin(), as.end());
89     printf("%d
", as.size());
90     for(int i = 0; i < as.size(); ++i) {
91         printf("%lld%c", as[i], i == as.size() - 1 ? '
' : ' ');
92     }
93     return 0;
94 }
View Code
原文地址:https://www.cnblogs.com/hzf-sbit/p/3898341.html