Submission #1153098

#TimeUsernameProblemLanguageResultExecution timeMemory
1153098tfgsFireworks (APIO16_fireworks)C++17
19 / 100
49 ms1096 KiB
#ifndef LOCAL #include <bits/stdc++.h> #endif using namespace std; #pragma GCC optimize("Ofast,unroll-loops,no-stack-protector") #pragma GCC target("avx2") #define int int64_t const int inf=1e18; #ifdef LOCAL #include "algo/debug.h" #else template <typename... Args> void dummy(Args&&... args){} #define ps dummy #endif #define f first #define s second template<class T> using V = vector<T>; using vi = V<int>; using vb = V<bool>; using vs = V<string>; #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) #define len(x) (int)((x).size()) #define rsz resize #define ins insert #define ft front() #define bk back() #define pb push_back #define lb lower_bound #define ub upper_bound #define ai2 array<int,2> #define ai3 array<int,3> #define ai4 array<int,4> #define ai5 array<int,5> template<class T> int lwb(const V<T>& a, const T& b) { return lb(all(a),b)-begin(a); } template<class T> int upb(const V<T>& a, const T& b) { return ub(all(a),b)-begin(a); } template<class T> bool ckmin(T& a, const T& b) { return a > b ? a=b, true : false; } template<class T> bool ckmax(T& a, const T& b) { return a < b ? a=b, true : false; } #define pct __builtin_popcountll #define ctz __builtin_ctzll #define clz __builtin_clzll constexpr int p2(int x) { return (int)1 << x; } constexpr int bits(int x) { return x == 0 ? 0 : 63-clz(x); } // floor(log2(x)) template<class T>void UNIQUE(V<T>& v) { sort(all(v)); v.erase(unique(all(v)),end(v)); } template<class T,class U>void erase(T& t, const U& u) { auto it = t.find(u); assert(it != end(t)); t.erase(it); } template<class F> struct y_combinator_result { F f; template<class T> explicit y_combinator_result(T &&f): f(std::forward<T>(f)) {} template<class ...Args> decltype(auto) operator()(Args &&...args) { return f(std::ref(*this), std::forward<Args>(args)...); } }; template<class Fun> decltype(auto) yy(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); } // In a tree, you are given that on every path from the root to a leaf there exists a red edge. // Prove that you can choose a subset of red edges that will cover each leaf exactly once. // Greedy: Sort the edges in inc order of depth, take it if the leaves were not already covered. // Remember that edges cover segments of leaves. // AFC some leaf was not covered. Then all the edges (segments) which cover it intersect another // edge (segment) that was used. But then this segment must completely contain the other segment // (can't be the other way around or else this leaf would be covered) and we would have taken // this segment first. const int N = 300, D = 300; int dp[N][D + 1]; V<ai2> sons[N]; void solve() { int n, m; cin >> n >> m; vi inp_d(n + m); for (int i = 1; i < n + m; i++) { int p, w; cin >> p >> w; p--; sons[p].pb({ i, w }); inp_d[i] = inp_d[p] + w; } for (int i = 0; i < n + m; i++) { for (int j = 0; j <= D; j++) { dp[i][j] = inf; } } for (int u = n; u < n + m; u++) dp[u][inp_d[u]] = 0; yy([&](auto rec, int u) -> void { if (u >= n) return; for (auto [v, w] : sons[u]) rec(v); for (int x = 0; x <= D; x++) { dp[u][x] = 0; for (auto [v, w] : sons[u]) { int mn = inf; for (int y = 0; y <= min(D, x + w); y++) { ckmin(mn, dp[v][y] + abs(y - x)); } if (mn == inf) dp[u][x] = inf; else dp[u][x] += mn; } } })(0); int ans = inf; for (int d = 0; d <= D; d++) ckmin(ans, dp[0][d]); cout << ans << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...