Codeforces 959-D Mahmoud and Ehab and another array construction task (贪心思想)

Problem Description

Mahmoud has an array a consisting of n integers. He asked Ehab to find another array b of the same length such that:

    b is lexicographically greater than or equal to a.
    bi ≥ 2.
    b is pairwise coprime: for every 1 ≤ i < j ≤ n, bi and bj are coprime, i. e. GCD(bi, bj) = 1, where GCD(w, z) is the greatest common divisor of w and z.

Ehab wants to choose a special array so he wants the lexicographically minimal array between all the variants. Can you find it?

An array x is lexicographically greater than an array y if there exists an index i such than xi > yi and xj = yj for all 1 ≤ j < i. An array x is equal to an array y if xi = yi for all 1 ≤ i ≤ n.

 

Input 

The first line contains an integer n (1 ≤ n ≤ 105), the number of elements in a and b.

The second line contains n integers a1, a2, ..., an (2 ≤ ai ≤ 105), the elements of a.

 

Output 

Output n space-separated integers, the i-th of them representing bi.

 

Examples

input
5
2 3 5 4 13
output
2 3 5 7 11 
input
3
10 3 7
output
10 3 7 

 

Note

Note that in the second sample, the array is already pairwise coprime so we printed it.

 

题意:

给出你n个数,然后让你改变这个序列,找出满足要求的另外一个序列。要求是每个数两两之间互质,然后要求新的序列字典序要大于等于第一个序列,但是要求找出字典序最小。

互质:公约数只有1的两个整数,叫做互质整数。公约数只有1的两个自然数,叫做互质自然数,后者是前者的特殊情形。

互质:若N个整数的最大公因数是1,则称这N个整数互质。

例如:8,10的最大公因数是2,不是1,因此不是整数互质。

          7,11,13的最大公因数是1,因此这是整数互质。

          5和5不互质,因为5和5的公因数有1、5

判别方法:

(1)两个不同的质数一定是互质数。

例如,2与7、13与19。

(2)一个质数,另一个不为它的倍数,这两个数为互质数。

例如,3与10、5与 26。

(3)1不是质数也不是合数,它和任何一个自然数(1本身除外)在一起都是互质数。如1和9908。

(4)相邻的两个自然数是互质数。如 15与 16。

(5)相邻的两个奇数是互质数。如 49与 51。

(6)较大数是质数的两个数是互质数。如97与88。

 

思路:

任意一对数互质,可以通过标记其质因子来解决,在找到第一个违背互质的数时,只需要找出大于该数的最小的一个与前面所有数互质的数,在此之后,要想保证字典序最小,便是所有可用的质数从小向大取。

具体实现:

每次输入一个数,就找出这个数的所有因子,然后把它们的因子的倍数标记。注意:在此处要优化一下:比如标记过的因子的倍数就不用再标记了。如果你输入的这个数被标记过,那么你将要修改这个数,而且题目要求字典序要大于等于第一个序列,所以你就从这个数开始,遍历直到找出一个满足没有被标记的数字,然后把它这个位置赋值,接着还需要把最新找到的这个数的因子及其因子的倍数标记,这样我们就满足了大于等于字典序的要求了,接着后面的数,从2开始遍历,依次找到没有被标记的数,然后赋值,注意:你每次找到一个数,还是要标记它的因子即因子倍数。
 

代码:

#include <bits/stdc++.h>
 
using namespace std;
 
int n,x;
const int Maxn = 2e6 + 100;
int prime[Maxn],vis[Maxn];
 
void makee(int x) {
    for(int i = x; i <= Maxn; i += x)
        vis[i] = 1;
    return ;
}
void fenjie(int x) {
    int i = 2;
    while(i <= x) {
        if(x % i == 0) {
            if(!prime[i])
                makee(i);
            prime[i] = 1;
            x /= i;
            i = 2;
        } else
            i++;
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n) {
        int flag =  0;
        int  y;
        memset(vis,0,sizeof(vis));
        memset(prime,0,sizeof(prime));
        int id = 2,cnt = 0;
        for(int i = 0; i < n; i++) {
            cin >> x;
            if(flag) {
                cnt = i;
                for(int j = id; j <= Maxn; j++) {
                    if(!vis[j]) {
                        cout << j << " ";
                        if(!prime[j])
                            makee(j);
                        id = j + 1;
                        break;
                    }
                }
                continue;
            }
            if(vis[x]) {
                for(int j = 2; j <= Maxn; j++)
                    if(!vis[j]) {
                        y = j;
                        cout << y << " " ;
                        flag = 1;
                        break;
                    }
                fenjie(y);
                vis[y] = 1;
            } else {
                cout << x << " ";
                fenjie(x);
                vis[x] = 1;
            }
        }
        cout <<endl;
    }
  }
}

 


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值