#include<bits/stdc++.h>
using namespace std;
#define int long long
// Parameter: N
// Method: init()!!! solve(x)
// Output: sorted list of proot (returned)
namespace proot {
const int N=1e6+5;
int pr[N+5];
bool check[N+5];
int phi[N+5];
int num;
void init() {
memset(check, false, sizeof(check));
phi[1]=1;
for(int i=2; i<=N; i++) {
if(!check[i]) {
pr[num++]=i;
phi[i]=i-1;
}
for(int j=0; j<num; j++) {
if(i*pr[j]>N) break;
check[i*pr[j]]=true;
if(i%pr[j]==0) {
phi[i*pr[j]]=phi[i]*pr[j];
break;
} else {
phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
}
}
void get(int n,vector<int>& fac) {
fac.clear();
for(int i=2; i*i<=n; i++)
if(n%i==0) {
fac.push_back(i);
while(n%i==0) n/=i;
}
if(n>1) fac.push_back(n);
}
int qpow(int x,int n,int mod) {
int ret=1;
for(; n; n>>=1) {
if(n&1) ret=ret*x%mod;
x=x*x%mod;
}
return ret;
}
vector<int> fac,ans;
bool ok(int x) {
if(x%2==0) x/=2;
if(x%2==0) return false;
for(int i=0; pr[i]*pr[i]<=x; i++) if(x%pr[i]==0) {
while(x%pr[i]==0) x/=pr[i];
return x==1;
}
return true;
}
int get_g(int p) {
for(int i=2; i<p; i++) {
bool flag=false;
for(int x:fac)
if(qpow(i,phi[p]/x,p)==1) {
flag=true;
break;
}
if(!flag&&qpow(i,phi[p],p)==1) return i;
}
}
void GetAns(int g,int p,vector<int>& ans) {
ans.clear();
ans.push_back(g);
for(int i=2; i<phi[p]; i++)
if(__gcd(i,phi[p])==1) ans.push_back(qpow(g,i,p));
}
vector<int> solve(int p) {
init();
if(p==2||p==4) return vector<int>{p-1};
if(!ok(p)) return vector<int>{};
get(phi[p],fac);
int g=get_g(p);
GetAns(g,p,ans);
sort(ans.begin(),ans.end());
return ans;
}
}
signed main() {
int T,x,d;
ios::sync_with_stdio(false);
proot::init();
cin>>T;
while(T--) {
cin>>x>>d;
vector <int> ans=proot::solve(x);
cout<<ans.size()<<endl;
for(int i=d;i<=ans.size();i+=d) cout<<ans[i-1]<<" ";
cout<<endl;
}
}
/*
4
25 2 36 1 9 6 18 1
[Output]
8
3 12 17 23
0
2
2
5 11
*/
【模板】原根
猜你喜欢
转载自www.cnblogs.com/mollnn/p/12344212.html
今日推荐
周排行