题解_CF1514C_Product_1_Modulo_N

题解_CF1514C_Product_1_Modulo_N

前言:

 场上这题整了三个小时没有证出来。所以以后有些题不证出来也要先找找规律出了。否则过于影响节奏。

题意:

Now you get Baby Ehab's first words: "Given an integer n, find the longest subsequence of 1,2,…,n−1 whose product is 11 modulo n." Please solve the problem.

A sequence bb is a subsequence of an array aa if bb can be obtained from aa by deleting some (possibly all) elements. The product of an empty subsequence is equal to 11.

Input

The only line contains the integer n,(2≤n≤10^5).

Output

The first line should contain a single integer, the length of the longest subsequence.

The second line should contain the elements of the subsequence, in increasing order.

If there are multiple solutions, you can print any.

解法:

 首先,我们对于给定的这 n-1 个数,只选取与 n 互质的数作为答案中出现的数。

 然后,我们将这n-1个数中与n互质的数乘起来(对n取模)最后会得到一个数m,如果m=1,那么答案就是所有与n互质的数,如果m!=1,那么m一定是出现在 1到n-1的所有与n互质的数中。那么我们只需要在答案中删掉m这个数即可。

证明:

 很显然,若i和n不互质,那么i的某个因数p(p!=1)一定是n的因数,那么如果i在答案中,那么所求答案序列的乘积中一定有p这个因数。根据 gcd(a,b) = gcd(b,a%b) 得到,gcd(n,m) = p != 1 所以答案中必然不会出现与n不互质的数。

    那么,问题的关键就在于,如何确定当m%p != 0的时候,m%n必然出现在1到n-1中与n互质的数中。很显然,因为m是所有小于n的与n互质的数的乘积,那么m中必然不含有n的因数(除了1),那么n%m一定与n互质。且n%m一定小于n(因为模过了)。因为小于n的所有与n互质的数现在都在答案序列里,且n%m也是一个比n小的与n互质的数,那么n%m一定属于答案序列。

代码:

#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1e5+7;
int ans[MAXN];
template <typename _TP>
inline _TP read(_TP &X){
    char ch=0;int w;X=0;
    while(!isdigit(ch)){w=ch=='-';ch=getchar();}
    while(isdigit(ch)){X=(X<<1)+(X<<3)+(ch^48);ch=getchar();}
    X=w?-X:X;
    return X;
}
long long gcd(long long a,long long b){
    while(b){a%=b;a^=b;b^=a;a^=b;}
    return a;
}
int main(){
    long long n,res=1,cnt=0;
    read(n);
    for(int i=1;i<=n;i++){
        if(gcd(i,n) == 1){
            ans[++cnt]=i;
            res*=i;
            res%=n;
        }
    }
    if(res!=1){
        cout<<cnt-1<<'\n';
    }
    else {
        cout<<cnt<<'\n';
    }
    for(int i=1;i<=cnt;i++){
        if(ans[i]!=res || res==1){
            cout<<ans[i]<<' ';
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值