Codeforces 959 D Mahmoud and Ehab and another array construction task
Discription
Mahmoud has an array a consisting of n integers. He asked Ehab to find another arrayb 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 isuch 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 andb.
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
5
2 3 5 4 13
2 3 5 7 11
3
10 3 7
10 3 7
Note
Note that in the second sample, the array is already pairwise coprime so we printed it.
字典序显然可以贪心,如果前若干位都和a一样的话,那么我们就找>=a[now] 的可以选的最小的数;否则就直接选现在可以取的最小的数。
然后我们每次选了一个数之和都要把有和这个数至少一个质因子相同的数给删掉,介于一个质因子只会被删一次,所以复杂度还是可靠的。。。
至于数最大处理到多少。。。。我一开始选的10^6然后正好RE了,,换成2*10^6就A 了 。。。。迷
主要是这个选小了会WA,选大了怕T。。。要是考试的时候就取一个最大的不会T的值吧2333.
#include<bits/stdc++.h> #define ll long long #define pb push_back using namespace std; const int maxn=2000000; const int inf=1e9; vector<int> D[maxn+5]; int MIN[maxn*4+5],n; int le,ri,now,num; bool v[maxn+5],F=0; inline void maintain(int o,int lc,int rc){ MIN[o]=min(MIN[lc],MIN[rc]); } void build(int o,int l,int r){ if(l==r){ MIN[o]=l; return;} int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1; build(lc,l,mid),build(rc,mid+1,r); maintain(o,lc,rc); } inline void init(){ for(int i=2;i<=maxn;i++) if(!v[i]) for(int j=i;j<=maxn;j+=i) v[j]=1,D[j].pb(i); build(1,1,maxn),memset(v,0,sizeof(v)); } void update(int o,int l,int r){ if(l==r){ MIN[o]=inf; return;} int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1; if(le<=mid) update(lc,l,mid); else update(rc,mid+1,r); maintain(o,lc,rc); } void query(int o,int l,int r){ if(l>=le&&r<=ri){ num=min(num,MIN[o]); return;} int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1; if(le<=mid) query(lc,l,mid); if(ri>mid) query(rc,mid+1,r); } inline void MDF(int x){ for(le=x;le<=maxn;le+=x) if(!v[le]) v[le]=1,update(1,1,maxn); } inline void solve(){ le=F?2:now,num=inf,ri=maxn,query(1,1,maxn); printf("%d ",num); if(num>now) F=1; for(int i=D[num].size()-1;i>=0;i--) MDF(D[num][i]); } int main(){ init(),scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&now); solve(); } return 0; }