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.
【题目大意】
给一个序列a,然后找到一个长度相等、字典序最小且大于等于a的新序列b,并满足任意序列中两个元素互质,数据范围序列长度是1~1e5,a,b的范围是2~1e5
【解题思路】
可以采用素数筛法的思想,先把1e5范围内的素数筛选出来,然后从前往后判断a数组的值是否能够符合和前面的数都互质的条件,简化处理可以转变为将满足条件的每个数分解为一些质数的乘积,然后这些质数的倍数都是不满足条件的数,可以加快判断的速度。如果出现了不满足条件的数就说明我们要在比它大的数当中找出一个满足条件的数,然后之后就变得简单了,因为这时b的字典序一定大于a的字典序,从2开始往后判断数是否已经被筛去,选择未被筛选的数组成剩下的b中的元素就可以得出最后的结果了。
【代码实现】
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
const int MAXN = 1500005;
int a[maxn], b[maxn];
bool isPrime[MAXN];
vector<int> primes;
void findPrime() {
for (int i = 2; i < maxn; ++i) {
if (!isPrime[i]) {
primes.push_back(i);
for (int j = i * 2; j < maxn; j += i) {
isPrime[j] = 1;
}
}
}
memset(isPrime, 0, sizeof(isPrime));
isPrime[0] = isPrime[1] = 1;
}
void fun(int a) {
if (isPrime[a])
return;
for (int i = a; i < MAXN; i += a) {
isPrime[i] = 1;
}
}
void judge(int a) {
for (int i = 0, l = primes.size(); i < l; ++i) {
if (a < primes[i] * 2)
break;
if (a % primes[i] == 0) {
fun(primes[i]);
while (a % primes[i] == 0)
{
a /= primes[i];
if (!a) return;
}
}
}
fun(a);
}
int main()
{
findPrime();
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", a + i);
}
int flag = 0;
for (int i = 0; i < n; ++i) {
if (isPrime[a[i]]) {
flag = i;
break;
}
b[i] = a[i];
judge(a[i]);
}
if (flag) {
for (int i = a[flag]; i < MAXN; ++i) {
if (!isPrime[i]) {
b[flag] = i;
judge(i);
break;
}
}
for (int i = flag + 1, j = 2; i < n; ++i) {
while (isPrime[j]) ++j;
b[i] = j;
fun(j);
}
}
for (int i = 0; i < n; ++i) {
printf("%s%d", i ? " " : "", b[i]);
}
putchar('
');
return 0;
}
Status | Accepted |
---|---|
Time | 140ms |
Memory | 2416kB |
Length | 1326 |
Lang | GNU G++17 7.2.0 |
Submitted | 2018-07-06 09:39:41 |
Shared | |
RemoteRunId | 40015452 |