This documentation is automatically generated by online-judge-tools/verification-helper
#include "Src/Utility/SeparatedFamilySet.hpp"
$U = { 0, 1, 2, \dots, U - 1}$ に対してある集合属 $S \subseteqq 2^{U}$ を計算する。 $S$ は以下の条件を満たす。
計算量: $O(U\log U)$
std::vector<std::vector<bool>> SeparatedFamilySet(usize U)
長さ $U$ のstd::vector<bool>
を $\text{card}(S)$ 個並べたstd::vector
を返す。
res[i][j]
は $i$ 番目の集合に $j$ が属しているか。
#pragma once
#include <algorithm>
#include <vector>
#include <concepts>
#include <ranges>
#include "../Template/TypeAlias.hpp"
namespace zawa {
// https://noshi91.hatenablog.com/entry/2024/05/31/012055
// 向きのついた分割
std::vector<std::vector<bool>> SeparatedFamilySet(usize U) {
const usize d = [&]() {
for (usize i = 1 ; ; i++) {
usize max = 1;
for (usize j = 0 ; j < (i / 2) ; j++) {
max *= i - j;
max /= j + 1;
}
if (max >= U) return i;
}
return U;
}();
std::vector res(d, std::vector<bool>(U));
std::vector<u8> in(d);
std::fill(in.rbegin(), in.rbegin() + d / 2, true);
for (usize idx = 0 ; idx < U ; idx++) {
for (usize i = 0 ; i < d ; i++) if (in[i]) {
res[i][idx] = true;
}
std::ranges::next_permutation(in);
}
return res;
}
} // namespace zawa
#line 2 "Src/Utility/SeparatedFamilySet.hpp"
#include <algorithm>
#include <vector>
#include <concepts>
#include <ranges>
#line 2 "Src/Template/TypeAlias.hpp"
#include <cstdint>
#include <cstddef>
namespace zawa {
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using usize = std::size_t;
} // namespace zawa
#line 9 "Src/Utility/SeparatedFamilySet.hpp"
namespace zawa {
// https://noshi91.hatenablog.com/entry/2024/05/31/012055
// 向きのついた分割
std::vector<std::vector<bool>> SeparatedFamilySet(usize U) {
const usize d = [&]() {
for (usize i = 1 ; ; i++) {
usize max = 1;
for (usize j = 0 ; j < (i / 2) ; j++) {
max *= i - j;
max /= j + 1;
}
if (max >= U) return i;
}
return U;
}();
std::vector res(d, std::vector<bool>(U));
std::vector<u8> in(d);
std::fill(in.rbegin(), in.rbegin() + d / 2, true);
for (usize idx = 0 ; idx < U ; idx++) {
for (usize i = 0 ; i < d ; i++) if (in[i]) {
res[i][idx] = true;
}
std::ranges::next_permutation(in);
}
return res;
}
} // namespace zawa