返回顶部

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;
    }
    
posted @ 2021-04-26 17:02  _Kolibri  阅读(84)  评论(0)    收藏  举报