Submission #900145

#TimeUsernameProblemLanguageResultExecution timeMemory
900145cadmiumskyClosing Time (IOI23_closing)C++17
75 / 100
648 ms69752 KiB
#include <bits/stdc++.h> #include "closing.h" #define all(x) (x).begin(),(x).end() using namespace std; using ll = long long; using ld = long double; #define int ll #define sz(x) ((int)(x).size()) using pii = pair<ll,ll>; using tii = tuple<int,int,int>; const int nmax = 3e3 + 5; vector<pii> g[nmax]; vector<ll> dX, dY; vector<int> occX; vector<int> chain; void dfs(int node, int f, vector<ll>& d, ll accum) { d[node] = accum; for(auto [x, c] : g[node]) if(x != f) dfs(x, node, d, accum + c); return; } void findchain(int node, int f, int Y) { if(sz(chain) && chain.back() == Y) return; chain.emplace_back(node); for(auto [x, e] : g[node]) { if(x == f) continue; findchain(x, node, Y); } if(chain.back() == Y) return; chain.pop_back(); } int disjointed(int n, ll K, int X, int Y) { priority_queue<pii, vector<pii>, greater<pii>> heap; vector<int> occY(n, 0); heap.emplace(0, Y); heap.emplace(0, X); int scorefromY = 0; while(!heap.empty()) { auto [C, node] = heap.top(); K -= C; if(K < 0) break; heap.pop(); occY[node] = 1; scorefromY++; for(auto [x, e] : g[node]) { if(occY[x]) continue; heap.emplace(C + e, x); } } return scorefromY; } const ll inf = ((ll)1e18) + 5; int X, Y; namespace DP { int foutu[nmax]; vector<ll> dp[nmax][2]; int dim[nmax][2]; void clear(int n) { for(int i = 0; i < n; i++) { dim[i][0] = dim[i][1] = 0; dp[i][0].clear(); dp[i][1].clear(); foutu[i] = 0; } } void convolute(vector<ll> a, vector<ll> b, vector<ll>& c) { c.resize(max(sz(c), sz(a) + sz(b) - 1), inf); //cerr << sz(a) << ' ' << sz(b) << ' ' << sz(c) << '\n'; for(int i = 0; i < sz(a); i++) for(int j = 0; j < sz(b); j++) c[i + j] = min(c[i + j], a[i] + b[j]); return; } void getdp(int node, int f) { // vectori??? dp[node][0].resize(2, inf); dp[node][1].resize(3, inf); dp[node][0][1] = min(dX[node], dY[node]); dp[node][1][2] = max(dX[node], dY[node]); //cerr << node << '\n'; for(auto [x, e] : g[node]) { if(x == f) continue; getdp(x, node); foutu[node] |= foutu[x]; } for(auto [x, e] : g[node]) { if(x == f) continue; vector<ll> tmp; if(!foutu[x]) tmp = dp[node][0]; convolute(dp[node][0], dp[x][0], tmp); dp[node][0] = move(tmp); tmp.clear(); if(!foutu[x]) tmp = dp[node][1]; convolute(dp[node][1], dp[x][1], tmp); convolute(dp[node][1], dp[x][0], tmp); dp[node][1] = move(tmp); } //cerr << node << ":\n"; //cerr << foutu[node] << '\n'; //for(auto x : dp[node][0]) cerr << x << ' '; cerr << '\n'; //for(auto x : dp[node][1]) cerr << x << ' '; cerr << '\n'; //cerr << "---\n"; foutu[node] = foutu[node] | (node == X || node == Y); return; } int getRestraint(int n, int root, ll K) { clear(n); //cerr << "\t\t\t" << root << '\n'; getdp(root, root); //cerr << "! " << sz(dp[root][1]) << '\n'; for(int i = sz(dp[root][1]) - 1; i >= 0; i--) if(dp[root][1][i] <= K) return i; return 0; } } #undef int int max_score(int n, int _X, int _Y, long long K, std::vector<int> U, std::vector<int> V, std::vector<int> W) { X = _X; Y = _Y; #define int ll for(int i = 0; i < n; i++) g[i].clear(); chain.clear(); dX.clear(); dY.clear(); occX.clear(); for(int i = 0; i < n - 1; i++) g[U[i]].emplace_back(V[i], W[i]), g[V[i]].emplace_back(U[i], W[i]); dX.resize(n); dY.resize(n); dfs(X, X, dX, 0); dfs(Y, Y, dY, 0); findchain(X, X, Y); int maxscore = disjointed(n, K, X, Y); int prv = X; for(auto x : chain) { if(dX[x] > dY[x]) { maxscore = max(maxscore, DP::getRestraint(n, prv, K)); break; } prv = x; } prv = Y; reverse(all(chain)); for(auto x : chain) { if(dY[x] > dX[x]) { maxscore = max(maxscore, DP::getRestraint(n, prv, K)); break; } prv = x; } return maxscore; } #undef int
#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...