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;
}