Submission #1277244

#TimeUsernameProblemLanguageResultExecution timeMemory
1277244pvproRoad Closures (APIO21_roads)C++20
100 / 100
365 ms57900 KiB
#include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <cstdio> #include <vector> #include <string> #include <stack> #include <queue> #include <deque> #include <bitset> #include <algorithm> #include <cmath> #include <set> #include <unordered_set> #include <map> #include <unordered_map> #include <chrono> #include <random> #include <complex> #include <numeric> #include <assert.h> #include <functional> #include <climits> #include <cstring> #include <iterator> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; using ll = long long; using ld = long double; using ushort = unsigned short; #define f first #define s second #define vec vector #define pii pair<int, int> #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define pb push_back #define mp make_pair template<typename T1, typename T2> istream& operator>> (istream &in, pair<T1, T2> &p) { in >> p.f >> p.s; return in; } template<typename T1, typename T2> ostream& operator<< (ostream &out, pair<T1, T2> p) { out << "(" << p.f << " " << p.s << ")"; return out; } #define printv(v) cerr << #v << " "; for (auto &x : v) { cerr << x << " "; } cerr << endl; #define printvv(v) cerr << #v << " "; for (auto &x : v) { for (auto &y : x) { cerr << y << " "; } cerr << endl; } #define debug(x) cerr << #x << " " << x << endl; template<typename T> istream& operator>> (istream &in, vector<T> &v) { for (auto &x : v) { in >> x; } return in; } template<typename T> ostream& operator<< (ostream &out, vector<T> v) { for (auto &x : v) { out << x << " "; } return out; } template<typename T> void operator-=(vector<T> &v, int delta) { for (auto &x : v) { x -= delta; } } template<typename T> void operator+=(vector<T> &v, int delta) { for (auto &x : v) { x += delta; } } mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; vector<vector<pii>> graph; vector<vector<long long>> A, B; vector<long long> da; vector<vector<long long>> S; vector<int> W; vector<vector<pii>> res(1e5 + 11); struct Node { Node *l, *r; ll x, y, sz, sum; Node (ll x_) { x = x_; l = nullptr; r = nullptr; sz = 1; sum = x; y = rnd(); } }; ll getSz(Node *root) { if (root) { return root->sz; } return 0; } ll getSum(Node *root) { if (root) { return root->sum; } return 0; } void update(Node *root) { root->sum = root->x + getSum(root->l) + getSum(root->r); root->sz = 1 + getSz(root->l) + getSz(root->r); } pair<Node*, Node*> split(Node *root, ll x) { if (root == nullptr) { return mp(root, root); } if (root->x < x) { auto p = split(root->r, x); root->r = p.f; update(root); return mp(root, p.s); } else { auto p = split(root->l, x); root->l = p.s; update(root); return mp(p.f, root); } } pair<Node*, Node*> splitSz(Node *root, ll x) { if (root == nullptr) { return mp(root, root); } if (getSz(root->l) < x) { auto p = splitSz(root->r, x - getSz(root->l) - 1); root->r = p.f; update(root); return mp(root, p.s); } else { auto p = splitSz(root->l, x); root->l = p.s; update(root); return mp(p.f, root); } } Node* merge(Node *a, Node *b) { if (a == nullptr) { return b; } if (b == nullptr) { return a; } if (a->y > b->y) { a->r = merge(a->r, b); update(a); return a; } else { b->l = merge(a, b->l); update(b); return b; } } Node *add(Node *root, ll x) { if (x > 0) { x = 0; } auto p = split(root, x); return merge(p.f, merge(new Node(x), p.s)); } Node *del(Node *root, ll x) { if (x > 0) { x = 0; } auto p = split(root, x); return merge(p.f, splitSz(p.s, 1).s); } ll get(Node *root, ll x) { auto p = splitSz(root, x); ll ans = getSum(p.f); merge(p.f, p.s); return ans; } int dfs(int v, int prev = -1, int w = 0) { res[v].clear(); for (auto &u : graph[v]) { if (u.f != prev) { int ans = dfs(u.f, v, u.s); res[v].pb(mp(ans, u.f)); } } if (res[v].empty()) { A[v] = {w, w}; B[v] = {w, 0}; W[v] = w; return v; } sort(all(res[v]), [&](pii a, pii b) { return A[a.f].size() > A[b.f].size(); }); while (A[res[v][0].f].size() <= graph[v].size()) { A[res[v][0].f].pb(A[res[v][0].f].back()); } while (B[res[v][0].f].size() <= graph[v].size()) { B[res[v][0].f].pb(B[res[v][0].f].back()); } for (int j = 0; j <= graph[v].size(); ++j) { if (B[res[v][0].f][j] < A[res[v][0].f][j] + da[res[v][0].f]) { S[j].pb(B[res[v][0].f][j] - A[res[v][0].f][j] - da[res[v][0].f]); } B[res[v][0].f][j] = A[res[v][0].f][j] + da[res[v][0].f]; } for (int j = graph[v].size() + 1; j < A[res[v][0].f].size(); ++j) { A[res[v][0].f][j] = min(A[res[v][0].f][j], B[res[v][0].f][j] - da[res[v][0].f]); B[res[v][0].f][j] = min(A[res[v][0].f][j] + da[res[v][0].f], B[res[v][0].f][j]); } vector<vector<pair<ll, ll>>> TA(graph[v].size() + 1); for (int i = 1; i < res[v].size(); ++i) { for (int j = 0; j < A[res[v][i].f].size(); ++j) { if (j <= graph[v].size()) { A[res[v][0].f][j] += A[res[v][i].f][j] + da[res[v][i].f]; B[res[v][0].f][j] += A[res[v][i].f][j] + da[res[v][i].f]; if (B[res[v][i].f][j] < A[res[v][i].f][j] + da[res[v][i].f]) { S[j].pb(B[res[v][i].f][j] - A[res[v][i].f][j] - da[res[v][i].f]); } } else { A[res[v][0].f][j] += min(A[res[v][i].f][j] + da[res[v][i].f], B[res[v][i].f][j]); B[res[v][0].f][j] += min(A[res[v][i].f][j] + da[res[v][i].f], B[res[v][i].f][j]); } } if (A[res[v][i].f].size() <= graph[v].size()) { TA[A[res[v][i].f].size()].pb(mp(A[res[v][i].f].back() + da[res[v][i].f], B[res[v][i].f].back() - A[res[v][i].f].back() - da[res[v][i].f])); } } Node *root = nullptr; ll dopX = 0; for (int i = 0; i <= graph[v].size(); ++i) { for (auto &p : TA[i]) { dopX += p.f; root = add(root, p.s); } for (auto &x : S[i]) { root = add(root, x); } A[res[v][0].f][i] += get(root, i) + dopX; B[res[v][0].f][i] += get(root, i - 1) + dopX; for (auto &x : S[i]) { root = del(root, x); } S[i].clear(); } da[res[v][0].f] += w; B[res[v][0].f][0] = A[res[v][0].f][0] + da[res[v][0].f]; return res[v][0].f; } std::vector<long long> minimum_closure_costs(int N, std::vector<int> U, std::vector<int> V, std::vector<int> w) { graph.assign(N, {}); A.assign(N, {}); B.assign(N, {}); da.assign(N, 0); W.assign(N, -1); S.assign(N, {}); vector<ll> fin(N); if (accumulate(all(U), 0ll) == 0) { sort(all(w)); for (int i = 1; i < N; ++i) { fin[N - i - 1] = fin[N - i] + w[i - 1]; } } else { for (int i = 0; i < N - 1; ++i) { graph[U[i]].pb(mp(V[i], w[i])); graph[V[i]].pb(mp(U[i], w[i])); } auto ans = dfs(0); for (int i = 0; i < A[ans].size(); ++i) { fin[i] = min(A[ans][i] + da[ans], B[ans][i]); } } return fin; } #ifdef LOCAL static void run_with_stack_size(signed (*func)(), size_t stsize) { char *stack, *send; stack = (char *)malloc(stsize); send = stack+stsize-16; send = (char *)((uintptr_t)send/16*16); asm volatile( "mov %%rsp, (%0)\n" "mov %0, %%rsp\n" : : "r" (send)); func(); asm volatile( "mov (%0), %%rsp\n" : : "r" (send)); free(stack); } int Main() { freopen("in.txt", "r", stdin); int N; assert(1 == scanf("%d", &N)); std::vector<int> U(N - 1), V(N - 1), W(N - 1); for (int i = 0; i < N - 1; ++i) { assert(3 == scanf("%d %d %d", &U[i], &V[i], &W[i])); // U[i] = i; // V[i] = i + 1; // W[i] = (rnd() % 1000000000) + 1; } std::vector<long long> closure_costs = minimum_closure_costs(N, U, V, W); for (int i = 0; i < static_cast<int>(closure_costs.size()); ++i) { if (i > 0) { printf(" "); } printf("%lld",closure_costs[i]); } printf("\n"); return 0; } signed main() { run_with_stack_size(Main, 1024*1024*1024); } #endif
#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...