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.
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 n space-separated integers, the i-th of them representing bi.
5 2 3 5 4 13
2 3 5 7 11
3 10 3 7
10 3 7
Note that in the second sample, the array is already pairwise coprime so we printed it.
题意是说:给定a 数组,让你找b数组,使得b满足b 的字典序恰能大于a,b的最小值大于1
且b数组的任何元素都两两互质。
思路 : 对于b中每一个数如果选中,我们标记他所有因子的倍数这样来去重,然后就可以沿着a的边界去找b。从0开始,如果a[I]没有标记b[i] = a[i] ; 否则b[i] 取第一个没被标记大于a[i]的数。并且以后取最小的没被标记的数。
#include <bits/stdc++.h>
using namespace std;
bool mk[10000006];
int fact[10000006];
void get()
{
int i = 1;
for(i = 2; i*i <= 10000000; i++)
{
if(fact[i] == 0)
{
fact[i] = i;
for(int j = i*i; j < 10000000; j+=i)
if(fact[j] == 0)
fact[j] = i;
}
}
while(i <= 10000000)
{
if(fact[i] == 0) fact[i] = i;
i++;
}
}
void sign(int x)
{
int a = fact[x];
while(x%a == 0) x/= a;
for(int i = a; i <= 10000000; i+=a)
mk[i] = 1;
if(x != 1) sign(x);
}
int main()
{
int n;
get();
scanf("%d",&n);
int yes = 0;
int k = 2;
for(int i = 0; i < n; i++)
{
int x;
scanf("%d",&x);
if(yes)
{
while(mk[k]) k++;
printf("%d ",k);
sign(k);
continue;
}
if(mk[x])
{
while(mk[x]) x++;
printf("%d ",x);
sign(x);
yes = 1;
continue;
}
printf("%d ",x);
sign(x);
}
return 0;
}