C. Product 1 Modulo N

原题链接
https://codeforces.ml/contest/1514/problem/C

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

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

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.

Examples
input

5
output
3
1 2 3
input
8
output
4
1 3 5 7
Note
In the first example, the product of the elements is 6 which is congruent to 1 modulo 5. The only longer subsequence is [1,2,3,4]. Its product is 24 which is congruent to 4 modulo 5. Hence, the answer is [1,2,3].

题意
给定一个n,要求从1到n - 1中选尽量多的数,使得这些数的乘积 %n 后等于1。
思路
首先,在所选的序列中,不能包含和n不互质的数,所有的数必须和n互质,将这些数都选完后,假设当前乘积 %n 的结果为p,如果p == 1,那么已经选了的数都可以选上。如果p != 1,那么我们希望让余数等于1,方法就是在刚刚选的数里面将p剔除,令剔除了p的乘积为 x ,可以理解为:x % n == 1, p * x % n == p,所以将p剔除后就可以使得乘积 %n 为1,可以证明,从1到n - 1中选取和n互质的数乘起来后再 %n 得到的余数p是和n互质的,所以可以在刚刚选取的数中找到p并剔除。
gcd(p % n, n) = gcd(p, n) = 1

代码

#include <iostream>
#include <vector>

using namespace std;

vector<int> ans;

int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}

int main()
{
    int n;
    cin >> n;
    
    long long now = 1;  // 不开会爆int
    for (int i = 1; i < n; i ++ )
        if (gcd(i, n) == 1)
        {
            ans.push_back(i);
            now = now * i % n;
        }
    
    if (now == 1)
    {
        cout << ans.size() << endl;
        for (auto x : ans) cout << x << ' ';
        puts("");
    }
    else
    {
        cout << ans.size() - 1 << endl;
        for (auto x : ans)
            if (x != now) cout << x << ' ';  // 将余数剔除
        puts("");
    }
    
    return 0;
}
posted on 2021-04-20 17:31  Laurance  阅读(229)  评论(0编辑  收藏  举报