//mod是指需要求mod的最小原根,phi是mod的phi函数值inlineintfind_root(constint&mod,constint&phi){staticint p[MaxCnt];staticint cnt;
cnt =0;int x = phi;for(int i =2; i * i <= phi;++i)if(x % i ==0){
p[++cnt]= i;while(x % i ==0)
x /= i;}if(x >1)
p[++cnt]= x;for(int g =1; g <= mod;++g){if(std::__gcd(g, mod)>1)continue;bool flg =true;for(int i =1; i <= cnt;++i)if(qpow(g, phi / p[i], mod)==1){
flg =false;break;}if(flg)return g;}return-1;}
3. 指标
3.1 定义
设 g 是 n 的一个原根,整数 a⊥n,则在模 φ(n) 意义下有唯一的整数 x,使得 gx≡a(modn),则称 x 为以 g 为底对模 n 的一个指标,记作 x=indga。
3.2 指标的性质
a≡b(modp)⇔indga≡indgb(modφ(p))
indg(ab)≡ind(a)+ind(b)(modφ(p))
indg(an)≡n×ind(a)(modφ(p))
3.3 求指标的方法
求指标的运算也叫做离散对数。
求指标即求 gx≡a(modp) 的最小自然数解。
使用 BSGS 算法即可。
4. N次剩余问题
问题:求解 xN≡a(modp) 在模 p 意义下的所有解,p 是质数。
首先我们知道,当 a≡0(modp) 时,方程只有 x=0 一个解。
否则 x∈[1,p)。
我们先找到 p 的最小原根 g。
因为 p 是质数且 p∤a,所以每个 x∈[1,p),我们都能找到 y=indgx 和 t=indga。
那么原方程等价于 yN≡t(mod(p−1))。
那么我们只需要用 exgcd 解这个简单的同余方程即可。
当 (N,p−1)∤t 时,原方程无解。
否则我们求出最小自然数解 y0,然后将在 [1,p) 内的 y=y0+k⋅(N,p−1)p−1(k∈Z) 的 y 记录下来。
#include<bits/stdc++.h>int p, K, a, g, t;int anscnt, ans[1000010];inlineintqpow(int a,int b,constint&p){int res =1;for(; b; b >>=1, a =1LL* a * a % p)if(b &1)
res =1LL* res * a % p;return res;}inlineintfind_root(constint&p){int n = p -1, x = p -1;staticint div[1000010], cnt;
cnt =0;for(int i =2; i * i <= n;++i)if(x % i ==0){
div[++cnt]= i;while(x % i ==0)
x /= i;}if(x >1)
div[++cnt]= x;for(int g =1; g <= p;++g){bool flg =true;for(int i =1; i <= cnt;++i)if(qpow(g,(p -1)/ div[i], p)==1){
flg =false;break;}if(flg)return g;}return-1;}inlineintsolve_BSGS(constint&a,constint&b,constint&p){
std::map<int,int> ha;
ha.clear();int t =ceil(sqrt(p)), x =1;for(int i =1; i <= t;++i){
x =1LL* x * a % p;
ha[1LL* x * b % p]= i;}int y = x;for(int i =1; i <= t;++i){if(ha.find(y)!= ha.end())return i * t - ha[y];
y =1LL* y * x % p;}return-1;}inlineintexgcd(constint&a,constint&b,int&x,int&y){if(!b)return x =1, y =0, a;int res =exgcd(b, a % b, y, x);
y -= a / b * x;return res;}intmain(){scanf("%d%d%d",&p,&K,&a);if(a ==0)returnputs("1\n0"),0;
g =find_root(p);
t =solve_BSGS(g, a, p);int x, y;int d =exgcd(p -1, K, x, y);if(t % d)returnputs("0"),0;int mod =(p -1)/ d;
y =(1LL* y *(t / d)% mod + mod)% mod;for(; y < p; y += mod)
ans[++anscnt]=qpow(g, y, p);
std::sort(ans +1, ans + anscnt +1);printf("%d\n", anscnt);for(int i =1; i <= anscnt;++i)printf("%d\n", ans[i]);return0;}