CF959D Solution
题解
对于\(b\)的3个限制,第1个仅由\(\not=a_i\)且字典位最高的\(b_i\)决定,第2个不要紧,第3个比较复杂。可以使用set维护当前全部满足第3个限制的\(b\)候选,埃氏筛求出\(b_i\)的全部质因数,并将其及其倍数于set中删除。如果每求出一个质因数均删除一遍时间不够,因此使用\(vis_i\)记录质因数\(i\)是否已由set中删除。若当前全部\(b_j=a_j\),为满足条件1需二分找出set中\(\ge a_i\)的最小\(b_i\),否则取最小\(b_i\)即可。
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,S=2e6;//S
int a[N],b[N]; bool vis[S];
set<int> s;
int main()
{
for(int i=2;i<=S;i++) s.insert(i);
int n; bool flag=0;//flag=1/0:是/否已出现b[i]>a[i]
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
if(!flag)
{
b[i]=*s.lower_bound(a[i]);
if(b[i]>a[i]) flag=1;
}
else b[i]=*s.begin();
s.erase(b[i]);
int t=b[i];
for(int j=2;j*j<=t;j++)
{
if(t%j) continue;
if(!vis[j])
for(int k=j;k<=S;k+=j) s.erase(k);
vis[j]=1;
while(t%j==0) t/=j;
}
if(t>1 && !vis[t])
for(int k=t;k<=S;k+=t) s.erase(k);
vis[t]=1;
}
for(int i=1;i<=n;i++) printf("%d ",b[i]);
return 0;
}