首先求p的原根g, g满足g^(phi(n)/pi) mod n 均不等于1,令g^y=x,g^t=a 得到 g^yk=g^t(modp) (a=0特判) 此式 可转化为 k*y=t(mod(phi(p))); 即 k*y=t(mod(p-1)),接下来就是求g^t=a(mod(p)) ,用babystep 求离散对数的方法求出t ,然后解模线性方程 k*y=t(mod(p-1)), 得到所有的y, y的解的个数为gcd(k,p-1),然后我们就可以求出所有的x,排序输出就行了
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<iostream>
#include<string>
#include<sstream>
#include<cctype>
#include<set>
#include<stack>
#include<functional>
#include<memory>
#include<deque>
#include<list>
#include<cmath>
#include<fstream>
#include<cstdlib>
#include<climits>
#include<iomanip>
#include<cstring>
#include<memory>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1,r,rt<<1|1
typedef long long LL;
typedef vector<unsigned int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
const int maxn = 40000;
const int mod = 1000000007;
const int hash_size = 175447;
const double pi = acos(-1.0);
const double eps = 1e-10;
bitset<maxn + 10> a;
int p[maxn], size;
void init() {
int i, j;
for (i = 2; i <= 200; ++i)
if (!a[i])
for (j = i * i; j <= maxn; a[j] = 1, j += i)
;
for (i = 2; i <= 40000; ++i)
if (!a[i])
p[size++] = i;
}
int f[maxn], c[maxn], cnt;
void spilt(int n) {
cnt = 0;
int i, t = n;
for (i = 0; i < size && p[i] * p[i] <= t; ++i) {
if (t % p[i] == 0) {
f[cnt] = p[i];
while (t % p[i] == 0) {
c[cnt]++;
t /= p[i];
}
cnt++;
}
}
if (t > 1) {
f[cnt] = t;
c[cnt]++;
cnt++;
}
}
int factor[maxn], tsize;
void dfs(int t, int dep) {
if (dep == cnt) {
factor[tsize++] = t;
return;
}
for (int i = 0; i <= c[dep]; t *= f[dep], ++i) {
dfs(t, dep + 1);
}
}
int POW(LL a, LL b, LL mod) {
LL res = 1;
while (b) {
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return (int) res;
}
int PrimitiveRoot(int n) {
if (n == 2)
return 1;
int i, j;
bool flag = false;
for (i = 2; i < n; ++i) {
flag = true;
for (j = 0; j < tsize; ++j) {
if (POW(i, factor[j], n) == 1) {
flag = false;
break;
}
}
if (flag)
return i;
}
return -1;
}
struct node {
LL key;
int val, next;
node() {
}
node(LL key, int val, int next) :
key(key), val(val), next(next) {
}
} edge[hash_size + 10];
struct HashMap {
int i, E;
int head[hash_size + 10];
void init() {
E = 0;
memset(head, -1, sizeof(head));
}
bool insert(LL key, int val) {
int u = key % hash_size;
for (i = head[u]; ~i; i = edge[i].next) {
if (edge[i].key == key)
return false;
}
edge[E] = node(key, val, head[u]);
head[u] = E++;
return true;
}
int find(LL key) {
int u = key % hash_size;
for (i = head[u]; ~i; i = edge[i].next) {
if (edge[i].key == key)
return edge[i].val;
}
return -1;
}
} Hash;
LL exgcd(LL a, LL b, LL &x, LL &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
LL d = exgcd(b, a % b, x, y);
LL t = x;
x = y;
y = t - (a / b) * y;
return d;
}
LL go(LL A, LL B, LL C) {
int i, m = (int) ceil(sqrt(C + 0.0));
Hash.init();
LL t = 1;
Hash.insert(1, 0);
for (i = 1; i <= m; ++i) {
t = t * A % C;
if (t == B)
return i;
Hash.insert(t, i);
}
LL P = 1, x, y;
for (i = 1; i <= m; ++i) {
P = P * t % C;
exgcd(P, C, x, y);
x *= B;
x = (x % C + C) % C;
y = Hash.find(x);
if (y >= 0)
return (int) (i * m + y);
}
return -1;
}
LL ans[maxn];
int Ccnt;
int main() {
ios::sync_with_stdio(false);
init();
int i, p, k, a;
scanf("%d%d%d", &p, &k, &a);
if (!a) {
puts("1");
puts("0");
return 0;
}
spilt(p - 1);
dfs(1, 0);
sort(factor, factor + tsize);
--tsize;
LL g = PrimitiveRoot(p);
LL t = go(g, a, p);
LL x, y, b = p - 1, M;
LL d = exgcd(k, b, x, y);
if (t % d) {
puts("0");
return 0;
}
M = b / d;
x *= t / d;
x = (x % M + M) % M;
for (i = 0; i < d; x = x + M, ++i) {
ans[Ccnt++] = POW(g, x, p);
}
sort(ans, ans + Ccnt);
printf("%d\n", Ccnt);
for (i = 0; i < Ccnt; ++i) {
printf("%I64d\n", ans[i]);
}
return 0;
}