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,求大于或者等于数组a字典序的数组b,满足任意i,j,gcd(bi, bj) = 1。并且是在所有满足条件中的字典序最小的一个。
题解:
对于第i个数先检验a[i]是否符合标准,若不符合,则后面的数直接找未选取的符合标准的最小素数,判断是否互质选择的做法是将之前的数质因子分解,标记质因子,此处比较麻烦的地方在于需要判断该数是否选取,若选取则将质因子标记,若不选取则不标记质因子。
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<algorithm>
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define FAST_IO ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const long long INF=0x7FFFFFFFFFFFFFFFLL;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
const int N=3e6;
int a[N+5],ans[N+5],vis[N+5],prime[N+5],cot,isprime[N+5];
void primeall()
{
for(int i=2;i<=sqrt(N);i++)
if(!isprime[i])
for(int j=i*i;j<=N;j+=i)
isprime[j]=1;
for(int i = 2; i <= N; ++i)
if(!isprime[i])
prime[++cot] = i;
}
int judge(int id,int flag)
{
for(int i=1;i<=cot && prime[i]*prime[i]<=id;i++)
{
if(!flag && id%prime[i]==0 && vis[prime[i]])
return 0;
if( flag && id%prime[i]==0) vis[prime[i]]=1;
while(id%prime[i]==0)
id/=prime[i];
}
if(id>1)
{
if(vis[id]) return 0;
if(flag) vis[id]=1;
}
return 1;
}
int work(int id)
{
if(judge(a[id],0))
{
judge(a[id],1);
ans[id]=a[id];
return 0;
}
for(int i=a[id]+1;;i++)
if(judge(i,0))
{
judge(i,1);
ans[id]=i;
break;
}
return 1;
}
int main()
{
primeall();
int n;
cin>>n;
int flag=0,no=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(flag)
{
while(vis[prime[no]])
no++;
ans[i]=prime[no++];
continue;
}
if(work(i))
flag=1;
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}