Codeforces Round #716 (Div. 2) C. Product 1 Modulo N (数论,良心证明)

-
题意:有一个\([1,2,...,n-1\)]的序列,要你构造出一个子序列,使得子序列的所有元素的乘积%\(n\)=1.
-
题解:首先我们构造出的子序列的乘积一定是\(k*n+1\),这个值一定和\(n\)互质.
证明:设\(gcd(k*n+1,n)=d\),那么\(d|k*n\),\(d|n\),\(d|1\),而整除\(1\)的数只能是\(1\),所以\(d=1\).
所以我们可以找出所有与\(n\)互质的数并求积,得到\(prod\),那么\(prod\)%\(n\)一定与\(n\)互质.
证明:假设余数为\(x\),那么\(prod\)=\(k*n+x\),即:\(k*n+x\)与\(n\)互质,而\(n|k*n\),所以\(x\)一定与\(n\)互质.
如果\(x=1\),那么\(prod\)就是答案.
否则,因为\(x<n\),所以这个余数\(x\)一定是\([1,n-1]\)中的一个质数,我们将它除去即可得到余数为\(1\).
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); ll n; cin>>n; vector<ll> ans; ll d=1; for(ll i=1;i<=n-1;++i){ if(gcd(i,n)==1){ ans.pb(i); d=(d*i)%n; } } if(d==1){ cout<<(int)ans.size()<<'\n'; for(auto w:ans) cout<<w<<' '; return 0; } cout<<(int)ans.size()-1<<'\n'; for(auto w:ans){ if(w==d) continue; cout<<w<<' '; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号