Codeforces Round #716 (Div. 2) C. Product 1 Modulo N 详细证明

题意:
给定 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 1n105

题解:
考虑最后的乘积一定是 k n + 1 , k ≥ 0 kn+1,k\geq0 kn+1,k0
则有 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,k0
则有 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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43900869/article/details/115878322
今日推荐