Submission #255453

#TimeUsernameProblemLanguageResultExecution timeMemory
255453EntityITDuathlon (APIO18_duathlon)C++14
0 / 100
183 ms30288 KiB
#include <bits/stdc++.h> using namespace std; #define ALL(x) (x).begin(), (x).end() #define SZ(x) static_cast<int>((x).size()) template<class T, size_t D> struct vec : vector<vec<T, D - 1>> { template<class... Args> vec(size_t n = 0, Args... args) : vector<vec<T, D - 1>>(n, vec<T, D - 1>(args...)) {} }; template<class T> struct vec<T, 1> : vector<T> { template<class... Args> vec(Args... args) : vector<T>(args...) {} }; template<class T> inline bool Minimize(T& a, const T& b) { return a > b ? a = b, true : false; } template<class T> inline bool Maximize(T& a, const T& b) { return a < b ? a = b, true : false; } inline int Next(int i, int n) { return i == n - 1 ? 0 : i + 1; } inline int Prev(int i, int n) { return !i ? n - 1 : i - 1; } mt19937 rng(static_cast<uint32_t>(chrono::steady_clock::now().time_since_epoch().count())); int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n_vertices, n_edges; cin >> n_vertices >> n_edges; vec<int, 2> neighbors_vertices(n_vertices); while (n_edges--) { int u, v; cin >> u >> v; --u; --v; neighbors_vertices[u].emplace_back(v); neighbors_vertices[v].emplace_back(u); } vec<int, 1> parents(n_vertices, -1), discoveries(n_vertices, -1), earliests(n_vertices, -1); int n_vertices_block_cut_tree = n_vertices; vec<int, 2> neighbors_vertices_block_cut_tree(n_vertices); function<void(int)> ConstructBlockCutTree = [&](int u) { static int current_discovery = -1; static stack<pair<int, int>> current_edges; discoveries[u] = earliests[u] = ++current_discovery; for (auto& v : neighbors_vertices[u]) { if (!~discoveries[v]) { parents[v] = u; current_edges.emplace(u, v); ConstructBlockCutTree(v); Minimize(earliests[u], earliests[v]); if (earliests[v] >= discoveries[u]) { vec<int, 1> vertices; do { vertices.emplace_back(current_edges.top().first); vertices.emplace_back(current_edges.top().second); current_edges.pop(); } while (vertices.rbegin()[1] != u || vertices.back() != v); sort(ALL(vertices)); vertices.erase(unique(ALL(vertices)), vertices.end()); neighbors_vertices_block_cut_tree.emplace_back(vec<int, 1>()); for (auto& vertex : vertices) { neighbors_vertices_block_cut_tree[vertex].emplace_back(n_vertices_block_cut_tree); neighbors_vertices_block_cut_tree[n_vertices_block_cut_tree].emplace_back(vertex); } ++n_vertices_block_cut_tree; } } else if (v != parents[u] && discoveries[v] < discoveries[u]) { current_edges.emplace(u, v); Minimize(earliests[u], discoveries[v]); } } }; for (int u = 0; u < n_vertices; ++u) { if (!~discoveries[u]) { ConstructBlockCutTree(u); } } int64_t answer = static_cast<int64_t>(n_vertices) * (n_vertices - 1) * (n_vertices - 2); vec<int, 1> a(n_vertices_block_cut_tree); function<int(int, int)> Solve = [&](int u, int parent) { a[u] = (u < n_vertices); for (auto& v : neighbors_vertices_block_cut_tree[u]) { if (v == parent) { continue; } a[u] += Solve(v, u); if (u >= n_vertices) { answer -= static_cast<int64_t>(SZ(neighbors_vertices_block_cut_tree[u]) - 1) * a[v] * (a[v] - 1); } } if (u >= n_vertices) { answer -= static_cast<int64_t>(SZ(neighbors_vertices_block_cut_tree[u]) - 1) * (n_vertices - a[u]) * ((n_vertices - a[u]) - 1); } return a[u]; }; Solve(0, -1); cout << answer << '\n'; 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...