Coprime AtCoder Beginner Contest 215

Coprime  

AtCoder Beginner Contest 215

 


Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400400 points

Problem Statement

Given a sequence of NN positive integers A=(A_1,A_2,\dots,A_N)A=(A1​,A2​,…,AN​), find every integer kk between 11 and MM (inclusive) that satisfies the following condition:

  • \gcd(A_i,k)=1gcd(Ai​,k)=1 for every integer ii such that 1 \le i \le N1≤i≤N.

Constraints

  • All values in input are integers.
  • 1 \le N,M \le 10^51≤N,M≤105
  • 1 \le A_i \le 10^51≤Ai​≤105

Input

Input is given from Standard Input in the following format:

NN MM
A_1A1​ A_2A2​ \dots… A_NAN​

Output

In the first line, print xx: the number of integers satisfying the requirement.
In the following xx lines, print the integers satisfying the requirement, in ascending order, each in its own line.


Sample Input 1 Copy

Copy

3 12
6 1 5

Sample Output 1 Copy

Copy

3
1
7
11

For example, 77 has the properties \gcd(6,7)=1,\gcd(1,7)=1,\gcd(5,7)=1gcd(6,7)=1,gcd(1,7)=1,gcd(5,7)=1, so it is included in the set of integers satisfying the requirement.
On the other hand, 99 has the property \gcd(6,9)=3gcd(6,9)=3, so it is not included in that set.
We have three integers between 11 and 1212 that satisfy the condition: 11, 77, and 1111. Be sure to print them in ascending order.

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

bool vis[N];

bool vis1[N];

int a[N];

int prime[N];

int ans[N];

int cnt;

int len;

int n, m;

set<int> se;

void get_prime() //线性筛法

{

    for (int i = 2; i <= N; i++)

    {

        if (!vis[i])

            prime[cnt++] = i;

        for (int j = 0; prime[j] <= N / i; j++)

        {

            vis[i * prime[j]] = 1;

            if (i % prime[j] == 0)

                break;

        }

    }

}

void find() // 因式分解,求所有的质因数

{

    for (int i = 0; i < n; i++)

    {

        int k = a[i];

        for (int j = 0; prime[j] <= k / prime[j]; j++)

        {

            if (k % prime[j] == 0)

            {

                se.insert(prime[j]);

                while (k % prime[j] == 0)

                    k = k / prime[j];

            }

        }

        if (k > 1)

            se.insert(k);

    }

}

void solve()

{

    scanf("%d%d", &n, &m);

    int i, j, k, l;

    for (i = 0; i < n; i++)

    {

        scanf("%d", &a[i]);

    }

    get_prime();

    find();

    for (auto &it : se) //利用埃式筛法的思想,去除所有质因数的倍数

    {

        if (it == 1)

            continue;

        for (j = it; j <= m; j += it)

            vis1[j] = 1;

    }

    for (i = 1; i <= m; i++)

    {

        if (!vis1[i])

            ans[len++] = i;

    }

    printf("%d\n", len);

    for (i = 0; i < len; i++)

    {

        printf("%d\n", ans[i]);

    }

}

signed main()

{

    solve();

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值