Submission #1302947

#TimeUsernameProblemLanguageResultExecution timeMemory
1302947SzymonKrzywdaDesignated Cities (JOI19_designated_cities)C++20
100 / 100
339 ms89272 KiB
#include <iostream> #include <vector> #include <set> using namespace std; using ll = long long; const ll MAXN = 2e5 + 7; vector<int> graf[MAXN]; ll koszt[MAXN][2]; bool wziete[MAXN]; int parent[MAXN]; ll ans[MAXN]; ll dp[MAXN]; int pre[MAXN][2]; int root = 1, aktpre = 0; void dfs(int v, int p) { pre[v][0] = aktpre++; parent[v] = p; for (int s : graf[v]) { if (s != p) dfs(s, v); } pre[v][1] = aktpre++; } ll dfs2(int v, int p) { for (int s : graf[v]) { if (s != p) { //cout << v << ' ' << dp[v] << ' ' << s << ' ' << koszt[s][1] << '\n'; dp[v] = max(dp[v], dfs2(s, v) + koszt[s][1]); } } return dp[v]; } void dfs3(int v, int p, ll maxrodzic, ll suma1) { ans[1] = max(ans[1], suma1); // cout << "OH: " << v << ' ' << dp[v] << ' ' << maxrodzic << ' ' << suma1 << '\n'; if (suma1 + max(maxrodzic, dp[v]) > ans[2]) { ans[2] = suma1 + max(maxrodzic, dp[v]); root = v; } multiset<ll, greater<ll>> secik; for (int s : graf[v]) { if (s != p){ secik.insert(dp[s] + koszt[s][1]); } } // cout << "U: "; // for (int val : secik) cout << val << ' '; // cout << '\n'; for (int s : graf[v]) { if (s == p) continue; //cout << *secik.begin() << ' ' << dp[s] + koszt[s][1] << ' ' << max(maxrodzic, *(++secik.begin())) << '\n'; if (*(secik.begin()) == dp[s] + koszt[s][1]) { if (secik.size() > 1) dfs3(s, v, max(maxrodzic, *(++secik.begin())) + koszt[s][0], suma1 -koszt[s][0] + koszt[s][1]); else dfs3(s, v, maxrodzic + koszt[s][0], suma1 - koszt[s][0] + koszt[s][1]); } else dfs3(s, v, max(maxrodzic, *secik.begin()) + koszt[s][0], suma1 - koszt[s][0] + koszt[s][1]); } } const int base = 1 << 19; ll tree[2 * base][2]; //{v, max} ll lazy[2 * base]; //{v, max} void push_l(int v) { tree[v * 2][1] += lazy[v]; tree[v * 2 + 1][1] += lazy[v]; lazy[2 * v] += lazy[v]; lazy[2 * v + 1] += lazy[v]; lazy[v] = 0; } void edit(int v, int vl, int vr, int l, int r, ll val) { if (vl > r || vr < l) return; if (l <= vl && vr <= r) { tree[v][1] += val; lazy[v] += val; return; } push_l(v); edit(v * 2, vl, (vl + vr) /2 , l, r, val); edit(v * 2 + 1, (vl + vr) / 2 + 1, vr , l, r, val); if (tree[v * 2][1] > tree[v * 2 + 1][1]) { tree[v][0] = tree[v * 2][0]; } else tree[v][0] = tree[v * 2 + 1][0]; tree[v][1] = max(tree[v * 2][1], tree[v * 2 + 1][1]); } void build(int v) { if (v >= base) return; build(v * 2); build(v * 2 + 1); if (tree[v * 2][1] > tree[v * 2 + 1][1]) { tree[v][0] = tree[v * 2][0]; } else tree[v][0] = tree[v * 2 + 1][0]; tree[v][1] = max(tree[v * 2][1], tree[v * 2 + 1][1]); } void dfs4(int v, int p, ll aktcost) { tree[base + pre[v][0]][1] = aktcost; tree[base + pre[v][0]][0] = v; for (int s : graf[v]) { if (s != p) dfs4(s, v, aktcost + koszt[s][1]); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); ll n, a, b, c , d; cin >> n; vector<pair<pair<ll, ll>, pair<ll, ll>>> kr; for (ll i = 0; i < n - 1; i++) { cin >> a >> b >> c >> d; graf[a].push_back(b); graf[b].push_back(a); kr.push_back({{a, b}, {c, d}}); } ll aktkoszt = 0; dfs(1, 1); for (auto & k : kr) { if (parent[k.first.second] == k.first.first) { swap(k.first.second, k.first.first); swap(k.second.first, k.second.second); } //cout << k.first.first << ' ' << k.first.second << ' ' << k.second.first << ' ' << k.second.second << '\n'; koszt[k.first.first][0] = k.second.first; koszt[k.first.first][1] = k.second.second; aktkoszt += k.second.first; } // for (int i = 1; i <= n; i++ ) { // cout << i << ": " << koszt[i][0] << ' ' << koszt[i][1] << '\n'; // } dfs2(1, 1); dfs3(1, 1, 0, aktkoszt); aktpre = 0; dfs(root, root); aktkoszt = 0; for (int i = 0; i < MAXN; i++) { koszt[i][0] = 0; koszt[i][1] = 0; } for (auto & k : kr) { if (parent[k.first.second] == k.first.first) { swap(k.first.second, k.first.first); swap(k.second.first, k.second.second); } //cout << k.first.first << ' ' << k.first.second << ' ' << k.second.first << ' ' << k.second.second << '\n'; koszt[k.first.first][0] = k.second.first; koszt[k.first.first][1] = k.second.second; aktkoszt += k.second.first; } ll suma = 0; for (int i = 1; i <= n; i++) suma += koszt[i][0] + koszt[i][1]; dfs4(root, root, 0); int licznik = 2; wziete[root] = 1; build(1); while (aktkoszt < suma) { int v = tree[1][0]; aktkoszt += tree[1][1]; //cout << v << ' ' << tree[1][1] << '\n'; while (!wziete[v]) { edit(1, 0, base - 1, pre[v][0], pre[v][1], -koszt[v][1]); wziete[v] = 1; v = parent[v]; } ans[licznik++] = aktkoszt; } for (int i = 1; i <= n; i++) ans[i] = max(ans[i - 1], ans[i]); //for (int i = 1; i <= n; i++) cout << suma - ans[i] << ' '; int q, val; cin >> q; while (q--) { cin >> val; cout << suma - ans[val] << '\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...