Submission #853064

#TimeUsernameProblemLanguageResultExecution timeMemory
853064mickey080929Closing Time (IOI23_closing)C++17
100 / 100
415 ms84440 KiB
#include "closing.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll inf = 2e18; struct SegmentTree{ int n, sz; vector<pair<ll,int>> tree; void init(int n_) { n = n_; sz = 1 << (__lg(n-1) + 1); tree.resize(sz<<1); build(); } void build() { for (int i=0; i<sz; i++) tree[sz+i] = {inf, i}; for (int i=sz-1; i>=1; i--) tree[i] = min(tree[i<<1], tree[i<<1|1]); }; void ins(int pos, ll val) { tree[pos+sz] = {val, pos}; for (pos += sz; pos > 1; pos >>= 1) tree[pos>>1] = min(tree[pos], tree[pos^1]); } void del(int tar) { ins(tar, inf); } pair<ll,int> get_top() { return tree[1]; } }; SegmentTree xtoa, xtoab, atoab, atox, abtoa; vector<int> par; vector<ll> distX, distY; vector<vector<pair<int,ll>>> adj; void dfs1(int x, int p) { for (auto &[y, c] : adj[x]) { if (y == p) continue; par[y] = x; distX[y] = distX[x] + c; dfs1(y, x); } } void dfs2(int x, int p) { for (auto &[y, c] : adj[x]) { if (y == p) continue; distY[y] = distY[x] + c; dfs2(y, x); } } void init(int n) { par.assign(n, 0); distX.assign(n, 0); distY.assign(n, 0); adj.assign(n, vector<pair<int,ll>>()); } int max_score(int N, int X, int Y, ll K, vector<int> U, vector<int> V, vector<int> W) { init(N); for (int i=0; i<N-1; i++) { adj[U[i]].emplace_back(V[i], (ll)W[i]); adj[V[i]].emplace_back(U[i], (ll)W[i]); } par[X] = -1; distX[X] = 0; dfs1(X, -1); distY[Y] = 0; dfs2(Y, -1); vector<ll> A(N, 0), B(N, 0); for (int i=0; i<N; i++) { A[i] = min(distX[i], distY[i]); B[i] = max(distX[i], distY[i]) - A[i]; } int ans = 0; ll sum = 0; vector<ll> t = A; sort(t.begin(), t.end()); for (int i=0; i<N; i++) { sum += t[i]; if (sum > K) break; ans ++; } vector<int> inpath(N, 0); int x = Y; int cnt = 0; while (x != -1) { inpath[x] = 1; cnt ++; x = par[x]; } vector<ll> cost1(2*cnt+1, 0), cost2(2*(N-cnt)+1, 0); t.clear(); xtoa.init(N); xtoab.init(N); atoab.init(N); atox.init(N); abtoa.init(N); for (int i=0; i<N; i++) { if (inpath[i]) { cost1[cnt] += A[i]; t.push_back(B[i]); } else { xtoa.ins(i, A[i]); xtoab.ins(i, A[i]+B[i]); } } sort(t.begin(), t.end()); for (int i=0; i<cnt; i++) cost1[cnt+i+1] = cost1[cnt+i] + t[i]; ll cur = 0; for (int i=1; i<=2*(N-cnt); i++) { ll t1 = xtoa.get_top().first; ll t2 = atoab.get_top().first; ll t3 = xtoab.get_top().first + abtoa.get_top().first; ll t4 = xtoab.get_top().first + atox.get_top().first; if (t1 < t2 && t1 < t3 && t1 < t4) { cur += t1; int idx = xtoa.get_top().second; xtoa.del(idx); xtoab.del(idx); atoab.ins(idx, B[idx]); atox.ins(idx, -A[idx]); } else if (t2 < t3 && t2 < t4) { cur += t2; int idx = atoab.get_top().second; atoab.del(idx); atox.del(idx); abtoa.ins(idx, -B[idx]); } else if (t3 < t4) { cur += t3; int idx1 = xtoab.get_top().second, idx2 = abtoa.get_top().second; xtoa.del(idx1); xtoab.del(idx1); atoab.ins(idx2, B[idx2]); atox.ins(idx2, -A[idx2]); abtoa.ins(idx1, -B[idx1]); abtoa.del(idx2); } else { cur += t4; int idx1 = xtoab.get_top().second, idx2 = atox.get_top().second; xtoa.del(idx1); xtoa.ins(idx2, A[idx2]); xtoab.del(idx1); xtoab.ins(idx2, A[idx2]+B[idx2]); atoab.del(idx2); atox.del(idx2); abtoa.ins(idx1, -B[idx1]); } cost2[i] = cur; } int j = 0; for (int i=cnt*2; i>=cnt; i--) { if (cost1[i] > K) continue; while (j < (N-cnt)*2 && cost1[i] + cost2[j+1] <= K) j ++; ans = max(ans, i + j); } 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...