Submission #1248585

#TimeUsernameProblemLanguageResultExecution timeMemory
1248585BoomydayClosing Time (IOI23_closing)C++20
8 / 100
104 ms34492 KiB
#include "closing.h" #include <bits/stdc++.h> using namespace std; using ll = long long; const ll INF = 1e18; vector<ll> distx, disty; vector<vector<pair<ll,int>>> adj; void get_dist(vector<ll>& dist, int u, int p = -1){ for(auto& [w, v]:adj[u]) if (v != p){ dist[v] = dist[u] + w; get_dist(dist, v, u); } } vector<ll> c1; vector<pair<ll,ll>> c2; int max_score(int N, int X, int Y, long long K, std::vector<int> U, std::vector<int> V, std::vector<int> W) { adj.clear(); adj.resize(N); for(int i=0;i<N-1;++i){ adj[U[i]].push_back({W[i], V[i]}); adj[V[i]].push_back({W[i], U[i]}); } distx.resize(N); disty.resize(N); distx[X] = 0; disty[Y] = 0; get_dist(distx, X); get_dist(disty, Y); // solve the first subtask int ans = 0; vector<ll> dists; for(int i=0;i<N;++i) dists.push_back(min(distx[i], disty[i])); sort(dists.begin(), dists.end()); ll kk = K; for(auto&d:dists){ if (kk < d) break; ans += 1; kk -= d; } // now time to try and get a better answer using greed approach kk = K; ll D = distx[Y]; vector<bool> is_path(N, 0); for(int i=0;i<N;++i){ if (distx[i] + disty[i] == D){ // this is a critical node if (distx[i] > disty[i]){ // far from x, connect to y kk -= disty[i]; } else { kk -= distx[i]; } is_path[i] = 1; } } // visit all the good nodes once if (kk < 0) return ans; // now maintain the caches c1.clear(); c2.clear(); for(int i=0;i<N;++i){ ll dif = abs(distx[i]-disty[i]); if(is_path[i]){ c1.push_back(0); c1.push_back(dif); } else { ll dst = min(distx[i], disty[i]); if (dst <= dif) { c1.push_back(dst); c1.push_back(dif); } else { c2.push_back({dst+dif, dst}); } } } sort(c1.begin(), c1.end()); sort(c2.begin(), c2.end()); // next we compute suffix minimums vector<ll> suf_min(c2.size()+1, INF); for(int i=c2.size()-1;i>=0;--i){ suf_min[i] = min(suf_min[i+1], c2[i].second); } // for twos taken there are 3 cases: // block of twos taken // block of 2s, 1, 2 // block of 2s, suffix min. // case 1: block of twos ll taken = 0; int numones = 0; for(int i=0;i<c2.size();++i) { taken += c2[i].first; } for(int numtwos = c2.size();numtwos >= 0; numtwos--){ if (taken > kk){ taken -= c2[numtwos-1].first; continue; } // add ones while (numones < c1.size() && taken + c1[numones] <= kk){ taken += c1[numones++]; } ans = max(ans, numones + 2*numtwos); } // case 2: block of twos and a suffix minimum taken = 0; numones = 0; for(int i=0;i<c2.size();++i) { taken += c2[i].first; } taken += suf_min[c2.size()]; for(int numtwos = c2.size();numtwos >= 0; numtwos--){ if (taken > kk){ if (numtwos == 0){ break; } taken -= suf_min[numtwos]; taken -= c2[numtwos-1].first; taken += suf_min[numtwos - 1]; continue; } // add ones while (numones < c1.size() && taken + c1[numones] <= kk){ taken += c1[numones++]; } ans = max(ans, numones + 2*numtwos + 1); } if (c2.size() < 2) return ans; taken = 0; numones = 0; for(int i=0;i<c2.size()-2;++i){ taken += c2[i].first; } taken += c2[c2.size()-2].second; taken += c2[c2.size()-1].first; // case 3: block of twos, one, two for(int numtwos = c2.size()-2;numtwos >= 0; numtwos--){ if (taken > kk){ if (numtwos == 0) break; taken -= c2[numtwos-1].first; taken -= c2[numtwos].second; taken -= c2[numtwos+1].first; taken += c2[numtwos-1].second; taken += c2[numtwos].first; continue; } // add ones while (numones < c1.size() && taken + c1[numones] <= kk){ taken += c1[numones++]; } ans = max(ans, numones + 2*numtwos + 3); } return ans; }
#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...