Submission #393937

#TimeUsernameProblemLanguageResultExecution timeMemory
393937KoDDuathlon (APIO18_duathlon)C++17
100 / 100
141 ms30492 KiB
#include <bits/stdc++.h> using i32 = std::int32_t; using u32 = std::uint32_t; using i64 = std::int64_t; using u64 = std::uint64_t; using i128 = __int128_t; using u128 = __uint128_t; using isize = std::ptrdiff_t; using usize = std::size_t; class rep { struct Iter { usize itr; constexpr Iter(const usize pos) noexcept : itr(pos) {} constexpr void operator++() noexcept { ++itr; } constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; } constexpr usize operator*() const noexcept { return itr; } }; const Iter first, last; public: explicit constexpr rep(const usize first, const usize last) noexcept : first(first), last(std::max(first, last)) {} constexpr Iter begin() const noexcept { return first; } constexpr Iter end() const noexcept { return last; } }; template <class F> struct RecLambda : private F { template <class G> explicit constexpr RecLambda(G&& g) : F(std::forward<G>(g)) {} template <class... Args> constexpr decltype(auto) operator()(Args&&... args) const { return F::operator()(*this, std::forward<Args>(args)...); } }; template <class G> explicit RecLambda(G&&) -> RecLambda<std::decay_t<G>>; template <class T> bool setmin(T& lhs, const T& rhs) { if (lhs > rhs) { lhs = rhs; return true; } return false; } template <class T> using Vec = std::vector<T>; void APIO18A_main() { usize N, M; std::cin >> N >> M; Vec<Vec<usize>> graph(N); while (M--) { usize a, b; std::cin >> a >> b; a -= 1; b -= 1; graph[a].push_back(b); graph[b].push_back(a); } Vec<Vec<usize>> bctree(N); const auto add_node = [&] { const auto ret = bctree.size(); bctree.push_back({}); return ret; }; Vec<usize> depth(N), ord(N), low(N); usize time = 0; std::stack<usize> store; const auto dfs = RecLambda( [&](auto&& dfs, const usize u, const usize p, const usize d) -> void { depth[u] = d; ord[u] = low[u] = time; time += 1; store.push(u); for (const auto v : graph[u]) if (v != p) { if (depth[v] == 0) { dfs(v, u, d + 1); if (ord[u] <= low[v]) { const auto node = add_node(); bctree[u].push_back(node); while (bctree[node].empty() or bctree[node].back() != v) { bctree[node].push_back(store.top()); store.pop(); } } setmin(low[u], low[v]); } else { setmin(low[u], ord[v]); } } }); Vec<usize> roots; for (const auto root : rep(0, N)) { if (depth[root] == 0) { dfs(root, root, 1); roots.push_back(root); } } Vec<usize> subtree(bctree.size()); u64 ans = 0; usize whole = 0; const auto calc = RecLambda([&](auto&& dfs, const usize u) -> void { subtree[u] = (u < N); for (const auto v : bctree[u]) { dfs(v); subtree[u] += subtree[v]; if (u >= N) { ans -= (u64)bctree[u].size() * subtree[v] * (subtree[v] - 1); } } }); const auto flush = RecLambda([&](auto&& dfs, const usize u) -> void { if (u >= N) { ans -= (u64)bctree[u].size() * (whole - subtree[u]) * (whole - subtree[u] - 1); } for (const auto v : bctree[u]) { dfs(v); } }); for (const auto root : roots) { calc(root); whole = subtree[root]; ans += (u64)whole * (whole - 1) * (whole - 2); flush(root); } std::cout << ans << '\n'; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); APIO18A_main(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...