test/aoj/1337/main.test.cpp
Depends on
Code
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1337"
#include <iostream>
#include <vector>
#include "Mylib/DataStructure/UnionFind/unionfind.cpp"
#include "Mylib/IO/input_tuple_vector.cpp"
#include "Mylib/Utils/compressor.cpp"
namespace hl = haar_lib;
const int H = 200;
const int W = 200;
int main() {
std::cin.tie(0);
std::ios::sync_with_stdio(false);
int n;
while (std::cin >> n, n) {
auto [l, t, r, b] = hl::input_tuple_vector<int, int, int, int>(n);
int64_t a[H][W] = {};
hl::compressor_builder<int>().add(l, r, -1).build().compress(l, r);
hl::compressor_builder<int>().add(t, b, -1).build().compress(t, b);
for (int i = 0; i < n; ++i) {
for (int x = l[i]; x < r[i]; ++x) {
for (int y = b[i]; y < t[i]; ++y) {
a[x][y] |= (1LL << i);
}
}
}
hl::unionfind uf(H * W);
int index[H][W];
{
int k = 0;
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
index[i][j] = k;
++k;
}
}
}
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
if (i + 1 < H and a[i][j] == a[i + 1][j]) uf.merge(index[i][j], index[i + 1][j]);
if (j + 1 < W and a[i][j] == a[i][j + 1]) uf.merge(index[i][j], index[i][j + 1]);
}
}
int ans = uf.count_groups();
std::cout << ans << "\n";
}
return 0;
}
#line 1 "test/aoj/1337/main.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1337"
#include <iostream>
#include <vector>
#line 2 "Mylib/DataStructure/UnionFind/unionfind.cpp"
#include <algorithm>
#include <numeric>
#line 5 "Mylib/DataStructure/UnionFind/unionfind.cpp"
namespace haar_lib {
class unionfind {
int n_, count_;
mutable std::vector<int> parent_;
std::vector<int> depth_, size_;
public:
unionfind() {}
unionfind(int n) : n_(n), count_(n), parent_(n), depth_(n, 1), size_(n, 1) {
std::iota(parent_.begin(), parent_.end(), 0);
}
int root_of(int i) const {
if (parent_[i] == i)
return i;
else
return parent_[i] = root_of(parent_[i]);
}
bool is_same(int i, int j) const { return root_of(i) == root_of(j); }
int merge(int i, int j) {
const int ri = root_of(i), rj = root_of(j);
if (ri == rj)
return ri;
else {
--count_;
if (depth_[ri] < depth_[rj]) {
parent_[ri] = rj;
size_[rj] += size_[ri];
return rj;
} else {
parent_[rj] = ri;
size_[ri] += size_[rj];
if (depth_[ri] == depth_[rj]) ++depth_[ri];
return ri;
}
}
}
int size_of(int i) const { return size_[root_of(i)]; }
int count_groups() const { return count_; }
auto get_groups() const {
std::vector<std::vector<int>> ret(n_);
for (int i = 0; i < n_; ++i) {
ret[root_of(i)].push_back(i);
}
ret.erase(
std::remove_if(
ret.begin(), ret.end(),
[](const auto &a) { return a.empty(); }),
ret.end());
return ret;
}
};
} // namespace haar_lib
#line 2 "Mylib/IO/input_tuple_vector.cpp"
#include <initializer_list>
#line 4 "Mylib/IO/input_tuple_vector.cpp"
#include <tuple>
#include <utility>
#line 7 "Mylib/IO/input_tuple_vector.cpp"
namespace haar_lib {
template <typename T, size_t... I>
void input_tuple_vector_init(T &val, int N, std::index_sequence<I...>) {
(void) std::initializer_list<int>{(void(std::get<I>(val).resize(N)), 0)...};
}
template <typename T, size_t... I>
void input_tuple_vector_helper(T &val, int i, std::index_sequence<I...>) {
(void) std::initializer_list<int>{(void(std::cin >> std::get<I>(val)[i]), 0)...};
}
template <typename... Args>
auto input_tuple_vector(int N) {
std::tuple<std::vector<Args>...> ret;
input_tuple_vector_init(ret, N, std::make_index_sequence<sizeof...(Args)>());
for (int i = 0; i < N; ++i) {
input_tuple_vector_helper(ret, i, std::make_index_sequence<sizeof...(Args)>());
}
return ret;
}
} // namespace haar_lib
#line 4 "Mylib/Utils/compressor.cpp"
namespace haar_lib {
template <typename T>
class compressor {
std::vector<T> data_;
template <typename>
friend class compressor_builder;
public:
int get_index(const T &val) const {
return std::lower_bound(data_.begin(), data_.end(), val) - data_.begin();
}
auto &compress(std::vector<T> &vals) const {
for (auto &x : vals) x = get_index(x);
return *this;
}
auto &compress(T &val) const {
val = get_index(val);
return *this;
}
template <typename U, typename... Args>
auto &compress(U &val, Args &... args) const {
compress(val);
return compress(args...);
}
auto &decompress(std::vector<T> &vals) const {
for (auto &x : vals) x = data_[x];
return *this;
}
auto &decompress(T &val) const {
val = data_[val];
return *this;
}
template <typename U, typename... Args>
auto &decompress(U &val, Args &... args) const {
decompress(val);
return decompress(args...);
}
int size() const { return data_.size(); }
T operator[](int index) const { return data_[index]; }
};
template <typename T>
class compressor_builder {
std::vector<T> data_;
public:
auto &add(const T &val) {
data_.push_back(val);
return *this;
}
auto &add(const std::vector<T> &vals) {
data_.insert(data_.end(), vals.begin(), vals.end());
return *this;
}
template <typename U, typename... Args>
auto &add(const U &val, const Args &... args) {
add(val);
return add(args...);
}
auto build() const {
compressor<T> ret;
ret.data_ = data_;
std::sort(ret.data_.begin(), ret.data_.end());
ret.data_.erase(std::unique(ret.data_.begin(), ret.data_.end()), ret.data_.end());
return ret;
}
};
} // namespace haar_lib
#line 8 "test/aoj/1337/main.test.cpp"
namespace hl = haar_lib;
const int H = 200;
const int W = 200;
int main() {
std::cin.tie(0);
std::ios::sync_with_stdio(false);
int n;
while (std::cin >> n, n) {
auto [l, t, r, b] = hl::input_tuple_vector<int, int, int, int>(n);
int64_t a[H][W] = {};
hl::compressor_builder<int>().add(l, r, -1).build().compress(l, r);
hl::compressor_builder<int>().add(t, b, -1).build().compress(t, b);
for (int i = 0; i < n; ++i) {
for (int x = l[i]; x < r[i]; ++x) {
for (int y = b[i]; y < t[i]; ++y) {
a[x][y] |= (1LL << i);
}
}
}
hl::unionfind uf(H * W);
int index[H][W];
{
int k = 0;
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
index[i][j] = k;
++k;
}
}
}
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
if (i + 1 < H and a[i][j] == a[i + 1][j]) uf.merge(index[i][j], index[i + 1][j]);
if (j + 1 < W and a[i][j] == a[i][j + 1]) uf.merge(index[i][j], index[i][j + 1]);
}
}
int ans = uf.count_groups();
std::cout << ans << "\n";
}
return 0;
}
Back to top page