\(T(T\leq 100)\) 组询问在模 \(P\) 意义下给 \(B\) 开 \(A\) 次方根,
求出 \([0,P)\) 的所有解,\(P\) 是一个质数。
求出 \(P\) 的原根 \(G\),若 \(G^x\equiv B\pmod{P}\),这个 \(x\) 可以通过 BSGS 求出来。
那么 \(X^A\equiv B\pmod{P}\) 就可以转换成 \(G^{kA}\equiv G^x\pmod{P}\)
其中 \(G^k\equiv X\pmod{P}\),那么 \(kA\equiv x\pmod{P-1}\)
用扩欧求出来 \(k\) 的所有解再带进去 \(G^k\) 算出所有的 \(X\)
#include <cstdio> #include <cctype> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const int MOD=70001; struct Linked_Hash{ struct node{int y,w,next;}E[MOD]; int Et,hs[MOD]; void Clear(){Et=0,memset(hs,-1,sizeof(hs));} void Insert(int w,int x){E[++Et]=(node){x,w,hs[w%MOD]},hs[w%MOD]=Et;} int locate(int W){ for (int i=hs[W%MOD];~i;i=E[i].next) if (E[i].w==W) return E[i].y; return -1; } }ha; int p,phi,P[MOD],ToT,g,a,m,ans[MOD],tot,prime[MOD],v[MOD],Cnt; int iut(){ int ans=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } void print(int ans){ if (ans>9) print(ans/10); putchar(ans%10+48); } void FJ(int p){ for (int i=1;prime[i]*prime[i]<=p;++i) if (p%prime[i]==0){ P[++ToT]=prime[i]; while (p%prime[i]==0) p/=prime[i]; } if (p>1) P[++ToT]=p; } int ksm(int x,int y,int p){ int ans=1; for (;y;y>>=1,x=1ll*x*x%p) if (y&1) ans=1ll*ans*x%p; return ans; } bool check(int x,int p){ if (ksm(x,phi,p)!=1) return 0; for (int i=1;i<=ToT;++i) if (ksm(x,phi/P[i],p)==1) return 0; return 1; } int Mn_Rt(int p){ for (int i=1;i<p;++i) if (check(i,p)) return i; return -1; } int BSGS(int a,int b,int mod){ ha.Clear(); int ir=sqrt(mod)+1,now=1; for (int i=0;i<ir;++i) ha.Insert(1ll*now*b%mod,i),now=1ll*now*a%mod; a=now,now=1; if (!a) return !b?1:-1; for (int i=0;i<=ir;++i){ int j=ha.locate(now); if (j>=0&&i*ir>=j) return i*ir-j; now=1ll*now*a%mod; } return -1; } int exgcd(int a,int b,int &x,int &y){ if (!b) {x=1,y=0; return a;} int Gcd=exgcd(b,a%b,y,x); y-=a/b*x; return Gcd; } int main(){ for (int i=2;i<MOD;++i){ if (!v[i]) prime[++Cnt]=i; for (int j=1;j<=Cnt&&prime[j]<=MOD/i;++j){ v[i*prime[j]]=1; if (i%prime[j]==0) break; } } for (int Test=iut();Test;--Test){ ToT=tot=0,p=iut(),a=iut(),m=iut(),FJ(phi=p-1),g=Mn_Rt(p); int b=phi,x,y,c=BSGS(g,m,p),Gcd=exgcd(a,b,x,y); if (c%Gcd) printf("No Solution\n"); else{ x=(1ll*x*(c/Gcd)%phi+phi)%phi; for (int i=1;i<=Gcd;++i) x=(x+b/Gcd)%phi,ans[++tot]=ksm(g,x,p); sort(ans+1,ans+1+tot),tot=unique(ans+1,ans+1+tot)-ans-1; for (int i=1;i<=tot;++i) print(ans[i]),putchar(i==tot?10:32); } } return 0; }