题意:
给定
n
n
n,问
[
1
,
n
)
[1,n)
[1,n)中至多可以取哪些数使得这些数的乘积模
n
n
n等于
1
1
1
数据范围:
1
≤
n
≤
1
0
5
1\leq n\leq 10^5
1≤n≤105
题解:
考虑最后的乘积一定是
k
n
+
1
,
k
≥
0
kn+1,k\geq0
kn+1,k≥0
则有
g
c
d
(
k
n
+
1
,
n
)
=
g
c
d
(
n
,
1
)
=
1
gcd(kn+1,n)=gcd(n,1)=1
gcd(kn+1,n)=gcd(n,1)=1
因此选择的任意一个数都必须与
n
n
n互质。
如果所有选择的数的乘积模
n
n
n的值
p
r
o
d
prod
prod为
1
1
1,则直接输出
否则将
p
r
o
d
prod
prod这个数删去后,再输出剩余的数即可。
证明若
p
r
o
d
prod
prod不为
1
1
1,则
p
r
o
d
prod
prod一定与
n
n
n互质:
实际结果为:
m
u
l
=
k
n
+
p
r
o
d
,
k
≥
0
mul=kn+prod,k\geq0
mul=kn+prod,k≥0
则有
g
c
d
(
m
u
l
,
n
)
=
g
c
d
(
k
n
+
p
r
o
d
,
n
)
=
g
c
d
(
p
r
o
d
,
n
)
gcd(mul,n)=gcd(kn+prod,n)=gcd(prod,n)
gcd(mul,n)=gcd(kn+prod,n)=gcd(prod,n)
可以知道的是,
m
u
l
mul
mul由所有的与
n
n
n互质的数相乘而来,因此
g
c
d
(
m
u
l
,
n
)
=
1
gcd(mul,n)=1
gcd(mul,n)=1,因此
g
c
d
(
p
r
o
d
,
n
)
=
1
gcd(prod,n)=1
gcd(prod,n)=1,故
p
r
o
d
prod
prod一定是被选择的数。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int st[N], ans[N], g;
int n, v;
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int main()
{
scanf("%d", &n);
v = 1;
for(int i = 1; i < n; ++i)
if(gcd(i, n) == 1) {
v = 1ll * v * i % n;
st[i] = 1;
}
if(v != 1) st[v] = 0;
for(int i = 1; i < n; ++i)
if(st[i]) ans[++g] = i;
printf("%d\n", g);
for(int i = 1; i <= g; ++i)
printf("%d%c", ans[i], " \n"[i == g]);
return 0;
}