제출 #1184187

#제출 시각아이디문제언어결과실행 시간메모리
1184187avighnaDesignated Cities (JOI19_designated_cities)C++20
16 / 100
339 ms131396 KiB
#include <bits/stdc++.h> template <typename T> class SparseTable { public: int maxPow; std::vector<T> orig; std::vector<std::vector<std::pair<T, int>>> table_max; SparseTable(const std::vector<T> &x) : orig(x) { const int n = x.size(); maxPow = std::floor(std::log2(n)); table_max = std::vector(maxPow + 1, std::vector<std::pair<T, int>>(n)); for (int i = 0; i < n; ++i) { table_max[0][i] = {x[i], i}; } for (int power = 1; power <= maxPow; ++power) { for (int i = 0; i < n - (1 << (power - 1)); ++i) { table_max[power][i] = std::max(table_max[power - 1][i], table_max[power - 1][i + (1 << (power - 1))]); } } } std::pair<T, int> query_max(int a, int b) { if (a == b) { return {orig[a], a}; } int powToUse = std::ceil(std::log2(b - a + 1)) - 1; return std::max(table_max[powToUse][a], table_max[powToUse][b - (1 << powToUse) + 1]); } }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int n; std::cin >> n; std::vector<std::vector<std::pair<int, std::pair<long long, long long>>>> adj( n + 1); long long tot = 0; for (int i = 0, a, b, c, d; i < n - 1; ++i) { std::cin >> a >> b >> c >> d; adj[a].push_back({b, {c, d}}); adj[b].push_back({a, {d, c}}); tot += c + d; } std::vector<long long> path_up(n + 1), path_down(n + 1), ans(n + 1), start(n + 1), end(n + 1); std::vector<std::pair<int, long long>> par(n + 1); long long up = 0, timer = 0; auto dfs = [&](auto &&self, int u, int p) -> void { start[u] = timer++; for (auto &[i, pr] : adj[u]) { if (i == p) { continue; } auto [c, d] = pr; par[i] = {u, c}; up += d; path_up[i] = path_up[u] + d; path_down[i] = path_down[u] + c; self(self, i, u); } end[u] = timer - 1; }; dfs(dfs, 1, 0); for (int i = 1; i <= n; ++i) { ans[1] = std::max(ans[1], up - path_up[i] + path_down[i]); } std::pair<int, int> start_nodes; auto dfs1 = [&](auto &&self, int u, int p, long long dep) -> std::pair<long long, int> { std::pair<long long, int> max_down = {path_down[u], u}; std::vector<std::pair<long long, int>> v; for (auto &[i, pr] : adj[u]) { if (i == p) { continue; } auto [c, d] = pr; v.push_back(self(self, i, u, dep + c)); max_down = std::max(max_down, v.back()); } long long _u_ = up + dep - path_up[u]; if (_u_ + (max_down.first - path_down[u]) > ans[2]) { ans[2] = _u_ + (max_down.first - path_down[u]); start_nodes = {u, max_down.second}; } std::sort(v.rbegin(), v.rend()); if (v.size() > 1) { if (_u_ + (v[0].first - path_down[u]) + (v[1].first - path_down[u]) > ans[2]) { ans[2] = _u_ + (v[0].first - path_down[u]) + (v[1].first - path_down[u]); start_nodes = {v[0].second, v[1].second}; } } return max_down; }; dfs1(dfs1, 1, 0, 0); // root at one of the start nodes and expand: anyways you will end up with the // first node being picked as the other start node int &node = start_nodes.first; up = timer = 0; path_down.assign(n + 1, 0), path_up.assign(n + 1, 0); dfs(dfs, node, 0); std::vector<long long> orig(n + 1); std::vector<int> get_node(n + 1); for (int i = 1; i <= n; ++i) { orig[start[i]] = path_down[i]; get_node[start[i]] = i; } SparseTable<long long> table(orig); int idx = 1; std::priority_queue<std::pair<int, int>> pq; pq.push({table.query_max(start[node], end[node]).first, get_node[table.query_max(start[node], end[node]).second]}); std::vector<bool> vis(n + 1); vis[node] = true; while (!pq.empty()) { auto [d, tar] = pq.top(); pq.pop(); idx++; auto temp = ans[idx]; ans[idx] = ans[idx - 1]; while (!vis[tar]) { vis[tar] = true; for (auto &[i, pr] : adj[tar]) { if (vis[i] or par[tar].first == i) { continue; } pq.push({table.query_max(start[i], end[i]).first, get_node[table.query_max(start[i], end[i]).second]}); } auto [p, wt] = par[tar]; ans[idx] += wt; tar = p; } if (idx == 2) { ans[idx] = temp; } } int q; std::cin >> q; while (q--) { int x; std::cin >> x; std::cout << tot - ans[x] << '\n'; } }
#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...