CF 1514C Product 1 Modulo N

Product 1 Modulo N

来源:https://codeforces.com/problemset/problem/1514/C
标签:【数学】【贪心】【思维】

题目简述

给定一个数n,找到[0,1,2,...,n-1]最长的子序列使子序列中1所有的数的乘积余n等于1。(b是a的子序列即b可由a删除若干个元素得到,可能是所有,规定一个空的序列代表1.)

Input
n (2≤n≤105).

Output
首先输出一个数,代表满足答案的最长序列的长度。
然后下一行输出满足条件的序列(任意一个)。

Sample Input_1

5

Sample Output_1

3
1 2 3

Sample Input_2

8

Sample Output_2

4
1 3 5 7

题目思路

和n的最大公约数为1的(即互质的),相乘结果肯定也和n互质,从1到n循环,把其都打上标记;选择一个数p作为这些数的乘积与n的余数;如果p!=1,则vis[p]=0,舍弃p;前面标记了的就是答案。因为如果p%n不为1,去掉p就相当于所有乘的结果不是选择乘p而是乘1,相应的%n的结果就会变为1。(至于为什么这样是最长的,我也不懂 -_-||| )

代码(附注释)

#include <bits/stdc++.h>
using namespace std;
bool vis[100005];

int main()
{
    int n;
    long long p=1;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
    	if(__gcd(n,i)==1){//与n互质
    		vis[i]=1;
    		p=(p*i)%n;
		}
    }
    if(p!=1) vis[p]=0;//舍弃p
    cout<<count(vis+1,vis+1+n,1)<<endl;
    for(int i=1;i<n;i++){
        if(vis[i]) cout<<i<<' ';
    }
    return 0;
}
原文地址:https://www.cnblogs.com/unravel-CAT/p/14803149.html