题目链接
You are given a prime number p, you want to find a permutation of numbers 1 , 2 , … , p − 1 1, 2, \dots, p-1 1,2,…,p−1, denoted as x 1 , x 2 , … , x p − 1 x_1, x_2, \dots, x_{p-1} x1,x2,…,xp−1, such that for all i ( 1 ≤ i ≤ p − 2 ) i (1\leq i\leq p-2) i(1≤i≤p−2), x i + 1 ≡ 2 x i ( m o d p ) x_{i+1}\equiv 2 x_i \pmod p xi+1≡2xi(modp)x or x i + 1 ≡ 3 x i ( m o d p ) x_{i+1} \equiv 3x_i \pmod p xi+1≡3xi(modp).
The first line contains an integer T ( 1 ≤ T ≤ 100 ) T (1\leq T\leq 100) T(1≤T≤100) indicating the number of test cases.
For each test case, there is one prime number p ( 2 ≤ p ≤ 1 0 6 ) p (2\leq p\leq 10^6) p(2≤p≤106) in the first line.
It’s guaranteed that ∑ p ≤ 1 0 6 \sum p\leq 10^6 ∑p≤106.
If there is no solution for this prime, print ‘-1’. Otherwise print p-1 integers x 1 , x 2 , … , x p − 1 x_1, x_2, \dots, x_{p-1} x1,x2,…,xp−1.
2
3
5
1 2
1 2 4 3
感觉是很捞的一道题,貌似只要暴力就过了,不难发现,从 1 1 1 开始选,能选 2 2 2 的倍数就选 2 ∗ x % n 2*x\%n 2∗x%n,能选 3 3 3 的倍数就选 3 ∗ x % n 3*x\%n 3∗x%n,不能选就输出 − 1 -1 −1 就行,AC代码如下:
#include
using namespace std;
typedef long long ll;
const int N=1e6+5;
int t,n,vis[N];
int main()
{
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof(vis));
scanf("%d",&n);
vector<int>ans;
ans.push_back(1);
vis[1]=1;
int cnt=1,flag=1;
while(1){
int a=ans.back(),ok=0;
if(!vis[a*2%n]&&a*2%n) {
vis[a*2%n]=1;
ans.push_back(a*2%n);
cnt++;
ok=1;
}else if(!vis[a*3%n]&&a*3%n){
vis[a*3%n]=1;
ans.push_back(a * 3 % n);
cnt++;
ok=1;
}
if(cnt==n-1) break;
if(ok==0){
flag=0;
break;
}
}
if(flag==0) printf("-1");
else for(auto i:ans) printf("%d ",i);
printf("\n");
}
return 0;
}