CodeForces 487C Prefix Product Sequence

洛谷传送门

CF 传送门

又是一道小清新构造题。

思路

显然若 \(n\) 为合数(除了 \(4\),因为 \(4\) 可以构造出 \([1,3,2,4]\))则无解,因为一定存在 \(x > 1,y > 1,x \ne y\)\(xy \equiv 0 \pmod{n}\),而 \(n\) 一定要放在排列最后一位使得前缀积仅有这一个 \(0\)

\(n\) 为质数时,有一种构造方法:\(i \in [2,n],p_i \equiv \dfrac{i}{i-1} \pmod{n}\)。显然前缀积依次为 \(1,2,3,...,n-1,0\)

代码

code
/*

p_b_p_b txdy
AThousandSuns txdy
Wu_Ren txdy
Appleblue17 txdy

*/

#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

ll n;

bool isprime(ll x) {
	for (ll i = 2; i * i <= x; ++i) {
		if (x % i == 0) {
			return 0;
		}
	}
	return 1;
}

ll qpow(ll b, ll p, ll mod) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

void solve() {
	scanf("%lld", &n);
	if (n == 1) {
		puts("YES\n1");
		return;
	}
	if (n == 2) {
		puts("YES\n1\n2");
		return;
	}
	if (n == 3) {
		puts("YES\n1\n2\n3");
		return;
	}
	if (n == 4) {
		puts("YES\n1\n3\n2\n4");
		return;
	}
	if (!isprime(n)) {
		puts("NO");
		return;
	}
	puts("YES\n1");
	for (int i = 2; i <= n; ++i) {
		printf("%lld\n", (i * qpow(i - 1, n - 2, n) - 1) % n + 1);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}
posted @ 2022-07-21 10:33  zltzlt  阅读(22)  评论(0编辑  收藏  举报