CF487C Prefix Product Sequence

题目描述

构造一个长度为$n$的排列,使得其前缀积在$\mod n$意义下两两不同

问题分析

我们发现构造这样一个序列必然有$1$放在第$1$个,$n$放在第$n$个,考虑$(n-1)!$模$n$的余数,可以证明如果$n$为大于$4$的合数,则该余数$=0$,于是无解。

现在我们考虑对于质数$n$怎么做。发现$1$到$(n-1)$都有模$n$意义下的逆元,于是我们可以构造一个序列满足它前缀积$\mod n$的余数是$1$到$n-1$,这样就是一个$ix \equiv (i+1) \mod n$,使用逆元求一下就好了

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# include <bits/stdc++.h>

# define R register
# define ll long long

const ll MaxN = 1e5 + 10;
ll n, tp, flag, p[MaxN];

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

ll exgcd(ll a, ll b, ll &x, ll &y)
{
ll g = a;
if(b == 0) x = 1, y = 0;
else g = exgcd(b, a % b, y, x), y -= (a / b) * x;
return g;
}

signed main()
{
scanf("%lld", &n);
if(n == 1) puts("YES\n1\n");
else if(n == 4) puts("YES\n1 3 2 4");
else if(check(n)) puts("NO");
else
{
printf("YES\n1 ");
for(ll i = 2; i < n; i++)
{
ll x, y;
exgcd(i - 1, n, x, y);
printf("%lld ", ((x * 1ll * i) % n + n) % n);
}
printf("%lld\n", n);
}
return 0;
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×