题意:
对于数字n, 问是否存在1~n的一个排列 使这个排列的每一个前缀的乘积模上n 可以是0~n-1的一个排列
解析:
通过观察1肯定要在首位,n一定要在最后
除4意外的合数都没有解
其他质数构造 a[i]=i*inv[i-1] , 这样用逆元把前面每个数的影响都消除掉
/* ***********************************************
Author :CKboss
Created Time :2015年03月12日 星期四 19时58分14秒
File Name :CF487C.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long int LL;
const int maxn=100100;
int n;
LL a[maxn],inv[maxn];
bool isprime(int x)
{
if(x==2||x==1) return true;
if(x%2==0) return false;
for(int i=3;i*i<=x;i+=2) if(x%i==0) return false;
return true;
}
void solve()
{
inv[1]=1LL;
for(int i=2;i<=n;i++) inv[i]=inv[n%i]*(n-n/i)%n;
a[1]=1LL; a[n]=n;
for(int i=2;i<n;i++) a[i]=(i*inv[i-1])%n;
for(int i=1;i<=n;i++) printf("%I64d\n",a[i]);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&n);
if(n==4)
{
puts("YES"); puts("1"); puts("3"); puts("2"); puts("4");
return 0;
}
if(isprime(n)==false) puts("NO");
else
{
puts("YES");
solve();
}
return 0;
}