Submission #1215895

#TimeUsernameProblemLanguageResultExecution timeMemory
1215895vaneaClosing Time (IOI23_closing)C++20
8 / 100
77 ms30276 KiB
#include <bits/stdc++.h> #include "closing.h" using namespace std; using ll = long long; const int mxN = 2e5+10; array<ll, 2> d[mxN]; vector<array<ll, 2>> adj[mxN]; bitset<mxN> assigned; array<bool, 2> vis[mxN]; ll val[mxN]; void dfs(int node, int p, int flag) { for(auto [it, dist] : adj[node]) { if(it == p) continue; d[it][flag] = d[node][flag]+dist; dfs(it, node, flag); } } int max_score(int N, int X, int Y, ll K, vector<int> U, vector<int> V, vector<int> W) { ll ans = 0, n = N; for(int i = 0; i < n-1; i++) { adj[U[i]].push_back({V[i], W[i]}); adj[V[i]].push_back({U[i], W[i]}); } d[X][0] = 0; dfs(X, -1, 0); d[Y][1] = 0; dfs(Y, -1, 1); set<array<ll, 5>> s; s.insert({0, 0, X, 0, 1}); s.insert({0, 0, Y, 1, 1}); for(auto [it, dist] : adj[X]) { s.insert({dist, 0, it, 0, 1}); vis[it][0] = true; } vis[X][0] = true; vis[Y][1] = true; for(auto [it, dist] : adj[Y]) { vis[it][1] = true; if(vis[it][0]) { ll dist1 = d[it][0], dist2 = d[it][1]; if(dist1 > dist2) swap(dist2, dist1); dist1 *= 2; if(dist1 > dist2) { s.erase({d[it][0], 0, it, 0, 1}); s.insert({dist2/2, dist2&1, it, 1, 2}); continue; } } s.insert({dist, 0, it, 1, 1}); } while(K > 0 && !s.empty()) { array<ll, 5> curr = *(s.begin()); ll dist = curr[0], odd = curr[1], u = curr[2], flag = curr[3], cnt = curr[4]; dist *= cnt; dist += odd; if(K < dist) { s.erase(s.begin()); continue; } K -= dist; ans += cnt; s.erase(s.begin()); if(!assigned[u] && cnt == 1) { assigned[u] = true; val[u] = dist; auto it = s.lower_bound({d[u][1-flag], 0, u, 1-flag, 1}); if(it != s.end() && (*it)[2] == u) { array<ll, 5> now = {(*it)[0]-dist, 0, u, 1-flag, 1}; s.erase(it); s.insert(now); } } for(auto [it, _] : adj[u]) { if(!vis[it][flag]) { vis[it][flag] = true; if(assigned[it]) { s.insert({d[it][flag]-val[it], it, flag}); } else if(vis[it][1-flag]) { ll dist1 = d[it][1-flag], dist2 = d[it][flag]; if(dist1 > dist2) swap(dist2, dist1); dist1 *= 2; if(dist1 > dist2) { s.erase({d[it][1-flag], 0, it, 1-flag, 1}); s.insert({dist2/2, dist2&1, it, flag, 2}); } else { s.insert({d[it][flag], 0, it, flag, 1}); } } else { s.insert({d[it][flag], 0, it, flag, 1}); } } if(cnt == 2) { flag = 1-flag; if(!vis[it][flag]) { vis[it][flag] = true; if(assigned[it]) { s.insert({d[it][flag]-val[it], it, flag}); } else if(vis[it][1-flag]) { ll dist1 = d[it][1-flag], dist2 = d[it][flag]; if(dist1 > dist2) swap(dist2, dist1); dist1 *= 2; if(dist1 > dist2) { s.erase({d[it][1-flag], 0, it, 1-flag, 1}); s.insert({dist2/2, dist2&1, it, 1, 2}); } else { s.insert({d[it][flag], 0, it, flag, 1}); } } else { s.insert({d[it][flag], 0, it, flag, 1}); } } } } } for(int i = 0; i < n; i++) { adj[i].clear(); assigned[i] = false; val[i] = 0; vis[i][0] = 0; vis[i][1] = 0; d[i][0] = 0; d[i][1] = 0; } return ans; } /*int main() { vector<int> a = {0, 0, 1, 2, 2, 5}, b = {1, 3, 2, 4, 5, 6}, c = {2, 3, 4, 2, 5, 3}; cout << max_score(7, 0, 2, 10, a, b, c) << ' '; vector<int> d = {0, 1, 2}, e = {1, 2, 3}, f = {18, 1, 19}; cout << max_score(4, 0, 3, 20, d, e, f); }*/
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...