結果
問題 | No.3031 曲面の向き付け |
ユーザー |
![]() |
提出日時 | 2025-02-21 23:46:49 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 381 ms / 2,000 ms |
コード長 | 4,821 bytes |
コンパイル時間 | 1,987 ms |
コンパイル使用メモリ | 137,148 KB |
実行使用メモリ | 39,112 KB |
最終ジャッジ日時 | 2025-02-21 23:46:57 |
合計ジャッジ時間 | 8,455 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 29 |
ソースコード
#include <iostream>#include <iomanip>#include <cassert>#include <vector>#include <algorithm>#include <utility>#include <set>#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#include <iterator>#include <limits>namespace zawa {template <class T>class CompressedSequence {private:std::vector<T> comped_;std::vector<u32> f_;public:static constexpr u32 NotFound = std::numeric_limits<u32>::max();CompressedSequence() = default;template <class InputIterator>CompressedSequence(InputIterator first, InputIterator last) : comped_(first, last), f_{} {std::sort(comped_.begin(), comped_.end());comped_.erase(std::unique(comped_.begin(), comped_.end()), comped_.end());comped_.shrink_to_fit();f_.reserve(std::distance(first, last));for (auto it{first} ; it != last ; it++) {f_.emplace_back(std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), *it)));}}CompressedSequence(const std::vector<T>& A) : CompressedSequence(A.begin(), A.end()) {}inline usize size() const noexcept {return comped_.size();}u32 operator[](const T& v) const {return std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), v));}u32 find(const T& v) const {u32 i = std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), v));return i == comped_.size() or comped_[i] != v ? NotFound : i;}bool contains(const T& v) const {u32 i = std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), v));return i < comped_.size() and comped_[i] == v;}u32 at(const T& v) const {u32 res{(*this)[v]};assert(res < size() and comped_[res] == v);return res;}inline u32 map(u32 i) const noexcept {assert(i < f_.size());return f_[i];}inline T inverse(u32 i) const noexcept {assert(i < size());return comped_[i];}};} // namespace zawastd::ostream& operator<<(std::ostream& os, std::pair<int, int> p) {os << '[' << p.first << ',' << p.second << ']';return os;}using namespace zawa;int N, A[100010], B[100010], C[100010];std::vector<std::pair<int, std::pair<int, int>>> g[100010];bool solve() {std::vector<std::pair<int, int>> app;for (int i = 0 ; i < N ; i++) {app.push_back({A[i], B[i]});app.push_back({B[i], C[i]});app.push_back({A[i], C[i]});}CompressedSequence comp{app};std::vector<std::vector<int>> vals(comp.size());for (int i = 0 ; i < N ; i++) {for (const auto& p : {std::pair{A[i], B[i]}, std::pair{B[i], C[i]}, std::pair{A[i], C[i]}}) {assert(p.first < p.second);auto it = comp.at(p);vals[it].push_back(i);}}for (int i = 0 ; i < (int)comp.size() ; i++) {if (vals[i].size() >= 3u) return false;if (vals[i].size() == 1u) continue;g[vals[i][0]].push_back({vals[i][1], comp.inverse(i)});g[vals[i][1]].push_back({vals[i][0], comp.inverse(i)});}std::vector<int> col(comp.size(), -1);auto assign = [&](int i, int c) -> bool {assert(0 <= i and i < (int)comp.size());// std::cout << "try " << comp.inverse(i) << ' ' << c << std::endl;if (col[i] == -1) col[i] = c;else {if (col[i] == c) return false;}return true;};// 0 hueru// 1 herustd::vector<bool> vis(N);auto dfs = [&](auto dfs, int v, int c) -> bool {// std::cout << "dfs " << A[v] << ' ' << B[v] << ' ' << C[v] << " col " << c << std::endl;if (!assign(comp.find({A[v], B[v]}), c)) return false;if (!assign(comp.find({B[v], C[v]}), c)) return false;if (!assign(comp.find({A[v], C[v]}), c ^ 1)) return false;vis[v] = true;for (const auto& [x, e] : g[v]) if (!vis[x]) {auto it = comp.at(e);int nc = col[it] ^ 1;if (e == std::pair{A[x], C[x]}) nc ^= 1;if (!dfs(dfs, x, nc)) return false;}return true;};for (int i = 0 ; i < N ; i++) if (!vis[i]) {if (!dfs(dfs, i, 0)) return false;}return true;}int main() {std::cin.tie(nullptr)->sync_with_stdio(false);std::cin >> N;for (int i = 0 ; i < N ; i++) std::cin >> A[i] >> B[i] >> C[i];std::cout << (solve() ? "YES\n" : "NO\n");}