Submission #1322222

#TimeUsernameProblemLanguageResultExecution timeMemory
1322222ChecksumClosing Time (IOI23_closing)C++20
100 / 100
172 ms51620 KiB
#include "closing.h" #include <bits/stdc++.h> using namespace std; using lint = long long; using pi = array<lint, 2>; #define sz(v) ((int)(v).size()) #define all(v) (v).begin(), (v).end() const int MAXN = 200005; pair<vector<lint>, vector<lint>> doConvex(vector<pi> p) { vector<lint> v; for (auto &[a, b] : p) { v.push_back(a); v.push_back(b - a); } sort(all(v)); reverse(all(v)); v.insert(v.begin(), 0); for (int i = 1; i < sz(v); i++) v[i] += v[i - 1]; vector<lint> ans[2]; for (int i = 0; i < sz(v); i++) { ans[(i + 1) % 2].push_back(v[i]); } return make_pair(ans[0], ans[1]); } pair<vector<lint>, vector<lint>> doConcave(vector<pi> p) { vector<lint> v[2]; sort(all(p), [&](const pi &a, const pi &b) { return a[1] > b[1]; }); vector<lint> curmin(sz(p) + 1); curmin[sz(p)] = -2e18; for (int i = sz(p) - 1; i >= 0; i--) { curmin[i] = max(curmin[i + 1], p[i][0]); } lint sum = 0; v[1].push_back(0); for (int i = 0; i < sz(p); i++) { sum += p[i][1]; v[1].push_back(sum); } sum = 0; lint bamax = -2e18; for (int i = 0; i < sz(p); i++) { sum += p[i][1]; bamax = max(bamax, p[i][0] - p[i][1]); v[0].push_back(max(sum + bamax, sum - p[i][1] + curmin[i])); } for (int i = 1; i + 1 < sz(v[0]); i++) { lint le = v[0][i] - v[0][i - 1]; lint ri = v[0][i + 1] - v[0][i]; assert(le >= ri); } return make_pair(v[0], v[1]); } vector<lint> solve(vector<pi> inp) { int n = sz(inp); lint sum = 0; vector<pi> convex, concave; for (auto &[a, b] : inp) { sum += b; a = b - a; if (a * 2 >= b) convex.push_back({a, b}); else concave.push_back({a, b}); } auto [odd1, even1] = doConcave(concave); auto [odd2, even2] = doConvex(convex); auto conv = [&](vector<lint> a, vector<lint> b) { if (sz(a) == 0) return b; if (sz(b) == 0) return a; vector<lint> v; lint sum = a[0] + b[0]; for (int i = 1; i < sz(a); i++) v.push_back(a[i] - a[i - 1]); for (int i = 1; i < sz(b); i++) v.push_back(b[i] - b[i - 1]); sort(all(v)); reverse(all(v)); v.insert(v.begin(), sum); for (int i = 1; i < sz(v); i++) v[i] += v[i - 1]; return v; }; vector<lint> ans(2 * n + 1, 0); { auto comb1 = conv(odd1, odd2); for (int i = 0; i < sz(comb1) && 2 * i + 2 < sz(ans); i++) ans[2 * i + 2] = max(ans[2 * i + 2], comb1[i]); } { auto comb1 = conv(odd1, even2); for (int i = 0; i < sz(comb1) && 2 * i + 1 < sz(ans); i++) ans[2 * i + 1] = max(ans[2 * i + 1], comb1[i]); } { auto comb1 = conv(even1, odd2); for (int i = 0; i < sz(comb1) && 2 * i + 1 < sz(ans); i++) ans[2 * i + 1] = max(ans[2 * i + 1], comb1[i]); } { auto comb1 = conv(even1, even2); for (int i = 0; i < sz(comb1) && 2 * i + 0 < sz(ans); i++) ans[2 * i + 0] = max(ans[2 * i + 0], comb1[i]); } for (auto &x : ans) x = sum - x; reverse(all(ans)); return ans; } vector<vector<pi>> gph; int par[MAXN]; lint dist[2][MAXN]; void dfs(int x, int p, int d) { for (auto &[w, y] : gph[x]) { if (y == p) continue; dist[d][y] = dist[d][x] + w; par[y] = x; dfs(y, x, d); } } int max_score(int N, int X, int Y, long long K, std::vector<int> U, std::vector<int> V, std::vector<int> W) { gph.clear(); gph.resize(N); for (int i = 0; i < N - 1; i++) { gph[U[i]].push_back({W[i], V[i]}); gph[V[i]].push_back({W[i], U[i]}); } for (int i = 0; i < N; i++) dist[0][i] = dist[1][i] = 0; dfs(Y, -1, 1); dfs(X, -1, 0); vector<int> chk(N); vector<int> paths; for (int i = Y; i != X; i = par[i]) { paths.push_back(i); chk[i] = 1; } paths.push_back(X); reverse(all(paths)); chk[X] = 1; vector<pi> coins; for (int i = 0; i < N; i++) { if (!chk[i]) { coins.push_back({dist[0][i], dist[1][i]}); } } for (auto &[x, y] : coins) if (x > y) swap(x, y); auto s1 = solve(coins); vector<lint> s2(sz(paths), 2e18); { vector<lint> g1(sz(paths)), g2(sz(paths)); lint tot = 0; for (int i = 0; i < sz(paths); i++) { tot += max(dist[1][paths[i]], dist[0][paths[i]]); g1[i] = max(dist[1][paths[i]], dist[0][paths[i]]) - dist[0][paths[i]]; g2[i] = max(dist[1][paths[i]], dist[0][paths[i]]) - dist[1][paths[i]]; } int l = 0, r = sz(paths); while (l < r) { s2[r - l - 1] = min(s2[r - l - 1], tot); if (g1[l] > g2[r - 1]) { tot -= g1[l++]; } else tot -= g2[--r]; } } int ans = 0; int j = sz(s2); for (int i = 0; i < sz(s1); i++) { while (j && s1[i] + s2[j - 1] > K) j--; if (j) ans = max(ans, i + j + sz(paths)); } { lint cursum = 0; vector<lint> sums; for (int i = 0; i < N; i++) { sums.push_back(dist[0][i]); sums.push_back(dist[1][i]); } sort(all(sums)); for (int i = 0; i < sz(sums); i++) { cursum += sums[i]; if (cursum > K) break; ans = max(ans, i + 1); } } 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...