[ABC215D] Coprime 2 题解
User_Unauthorized · · 题解
题意
给定数列
题解
本题存在线性复杂度算法。
记
考虑线性筛筛出合数的过程,合数
首先对数列
现在我们已经处理出了所有在这个数列中出现的质因子,易证符合题目条件的
考虑到本题数据过水,不能体现出线性算法的效率,所以造了一个加强版:T358758。
Code
//A
#include <bits/stdc++.h>
typedef int valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<bool> bitset;
constexpr valueType MAX = 1e5 + 5;
int main() {
std::ios_base::sync_with_stdio(false);
valueType N, M;
std::cin >> N >> M;
ValueVector source(N);
for (auto &iter: source)
std::cin >> iter;
ValueVector father(MAX + 1, 1);
bitset tag(MAX + 1, true);
ValueVector primeList;
primeList.reserve(std::ceil((long double) MAX / std::log((long double) MAX)));
for (valueType i = 2; i <= MAX; ++i) {
if (__builtin_expect(tag[i], false)) {
father[i] = 1;
primeList.emplace_back(i);
}
for (auto const &iter: primeList) {
valueType const t = iter * i;
if (t > MAX)
break;
tag[t] = false;
father[t] = i;
if (__builtin_expect(i % iter == 0, false))
break;
}
}
std::fill(tag.begin(), tag.end(), false);
typedef std::function<void(valueType)> TagFunction;
TagFunction solve = [&father, &tag](valueType n) {
while (n > 1 && !tag[n]) {
tag[n] = true;
tag[n / father[n]] = true;
n = father[n];
}
};
for (auto const &iter: source)
solve(iter);
tag[1] = false;
for (valueType i = 2; i <= MAX; ++i)
tag[i] = tag[i] || (tag[father[i]] || tag[i / father[i]]);
ValueVector result;
result.reserve(M);
result.push_back(1);
for (valueType i = 2; i <= M; ++i)
if (!tag[i])
result.push_back(i);
std::cout << result.size() << '\n';
for (auto const &iter: result)
std::cout << iter << '\n';
std::cout << std::flush;
return 0;
}