小清新构造题

小清新构造题。

好像下面题解都没有说 \(n=p^2(p\ge 3)\) 的时候为什么不行,来补一发。

事实上很简单,\(1< p<2p<n\),所以至少有两个 \(b_i\)\(\mod n\)\(0\) 的。

然后 \(n=pq(1<p<q<n)\) 的时候,直接考虑 \(p,q\) 两个数可以发现也会导致冲突。

因此仅有 \(n=1,4\ \text{or}\ n\ \text{is prime}\) 的时候有解。

数据点里面塞了个 \(n=1\),令我非常 /tuu。

然后 \(n=4\) 的时候直接手玩 1 3 2 4\(n\ \text{is prime}\) 的时候考虑以下构造:\(1,2\times 1^{-1}\bmod n,3\times 2^{-1}\bmod n\dots((n-1)\times (n-2)^{-1})\bmod n,n\)

发现 \(b_i\bmod n\) 分别是 \(1,2,3,\dots n-1,0\)

然后有 \(n\ \text{is prime}\) 的条件因此可以直接上费马小定理求逆元。

代码

#include<bits/stdc++.h>
#define N 100009
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
inline ll read() {
    ll x=0,f=1;int c=getchar();
    while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)) {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
ll n,a[N],pr[N],cnt;
bool vst[N];
void prime(ll n){
	for(int i=2;i<=n;i++){
		if(!vst[i]) pr[++cnt]=i;
		for(int j=1;j<=cnt&&i*pr[j]<=n;j++){
			vst[i*pr[j]]=1;
			if(i%pr[j]==0) break;
		}
	}
}
ll qpow(ll x,ll pw){
    ll ans=1;
    while(pw){
        if(pw&1) ans=ans*x,ans%=n;
        x*=x,x%=n,pw>>=1;
    }
    return ans;
}
int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    prime(100000);
    n=read();
    if(n==1){printf("YES\n1\n");return 0;}
    if(n!=4&&vst[n]==1){printf("NO\n");return 0;}
    if(n==4){printf("YES\n1\n3\n2\n4");return 0;}
    printf("YES\n1\n");
    for(int i=2;i<=n-1;i++) printf("%lld\n",1ll*i*qpow(i-1,n-2)%n);
    printf("%lld",n);
    return 0;
}
posted @ 2021-12-06 21:37  Rolling_Code  阅读(86)  评论(0)    收藏  举报