Submission #1109704

#TimeUsernameProblemLanguageResultExecution timeMemory
1109704_callmelucianDesignated Cities (JOI19_designated_cities)C++14
100 / 100
332 ms60944 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef pair<ll,ll> pl; typedef pair<int,int> pii; typedef tuple<int,int,int> tpl; #define all(a) a.begin(), a.end() #define filter(a) a.erase(unique(all(a)), a.end()) const int mn = 2e5 + 5; struct IT { vector<pl> tr; vector<ll> lazy; IT (int sz) : tr(4 * sz), lazy(4 * sz) {} void apply (int k, ll val) { tr[k].first += val, lazy[k] += val; } void pushDown (int k) { if (lazy[k]) apply(2 * k, lazy[k]), apply(2 * k + 1, lazy[k]), lazy[k] = 0; } void indexing (int pos, int val, int k, int l, int r) { for (; l < r;) { int mid = (l + r) >> 1; if (pos <= mid) k <<= 1, r = mid; else k <<= 1, k |= 1, l = mid + 1; } tr[k] = make_pair(0, val); for (k /= 2; k; k /= 2) tr[k] = max(tr[2 * k], tr[2 * k + 1]); } void update (int a, int b, ll val, int k, int l, int r) { if (b < l || r < a) return; if (a <= l && r <= b) return apply(k, val), void(); pushDown(k); int mid = (l + r) >> 1; update(a, b, val, 2 * k, l, mid); update(a, b, val, 2 * k + 1, mid + 1, r); tr[k] = max(tr[2 * k], tr[2 * k + 1]); } pl query (int a, int b, int k, int l, int r) { if (b < l || r < a) return make_pair(0, 0); if (a <= l && r <= b) return tr[k]; pushDown(k); int mid = (l + r) >> 1; return max(query(a, b, 2 * k, l, mid), query(a, b, 2 * k + 1, mid + 1, r)); } }; vector<tpl> adj[mn]; ll ans[mn], n; namespace originalTree { int bestLeaf[mn], secLeaf[mn]; ll downPath[mn], upPath[mn], sumDown; void dfs (int u, int p, ll pA, ll pH) { // construct costs on paths downPath[u] = downPath[p] + pA; upPath[u] = upPath[p] + pH; bestLeaf[u] = u; // run dfs down for (tpl item : adj[u]) { int v, away, home; tie(v, away, home) = item; if (v == p) continue; dfs(v, u, away, home); sumDown += away; if (downPath[bestLeaf[v]] > downPath[bestLeaf[u]]) secLeaf[u] = bestLeaf[u], bestLeaf[u] = bestLeaf[v]; else if (downPath[bestLeaf[v]] > downPath[secLeaf[u]]) secLeaf[u] = bestLeaf[v]; } } ll tryNode (int u) { ll pathOne = downPath[bestLeaf[u]] - (bestLeaf[u] ? downPath[u] : 0); ll pathTwo = downPath[secLeaf[u]] - (secLeaf[u] ? downPath[u] : 0); return sumDown - pathOne - pathTwo - downPath[u] + upPath[u]; } ll chooseNode (int u) { return sumDown - downPath[u] + upPath[u]; } } namespace modifiedTree { int num[mn], sz[mn], up[mn], timeDfs; bool colored[mn]; ll weight[mn]; IT tree(mn); bool dfs (int u, int p, int y, ll w) { num[u] = ++timeDfs, sz[u] = 1, up[u] = p, weight[u] = w; if (u == y) colored[u] = 1; tree.indexing(num[u], u, 1, 1, n); for (tpl item : adj[u]) { int v, away, home; tie(v, away, home) = item; if (v == p) continue; if (dfs(v, u, y, away)) colored[u] = 1; sz[u] += sz[v]; } if (!colored[u]) tree.update(num[u], num[u] + sz[u] - 1, w, 1, 1, n); return colored[u]; } pl pickCand() { return tree.query(1, n, 1, 1, n); } void colorNode (int u) { while (!colored[u]) { tree.update(num[u], num[u] + sz[u] - 1, -weight[u], 1, 1, n); colored[u] = 1, u = up[u]; } } }; int main() { ios::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 1; i < n; i++) { int a, b, c, d; cin >> a >> b >> c >> d; adj[a].emplace_back(b, c, d); adj[b].emplace_back(a, d, c); } originalTree::dfs(1, 1, 0, 0); for (int i = 1; i <= n; i++) ans[i] = LLONG_MAX; int optX = 0, optY = 0; for (int i = 1; i <= n; i++) { ll cur = originalTree::tryNode(i); if (cur < ans[2]) ans[2] = cur, optX = originalTree::bestLeaf[i], optY = originalTree::secLeaf[i]; ans[1] = min(ans[1], originalTree::chooseNode(i)); } modifiedTree::dfs(optX, optX, optY, 0); for (int i = 3; i <= n; i++) { ll delta; int node; tie(delta, node) = modifiedTree::pickCand(); ans[i] = ans[i - 1] - delta; modifiedTree::colorNode(node); } int q; cin >> q; while (q--) { int E; cin >> E; cout << ans[E] << "\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...