Submission #1134259

#TimeUsernameProblemLanguageResultExecution timeMemory
1134259steveonalexMagic Tree (CEOI19_magictree)C++20
100 / 100
375 ms188748 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){return __gcd(a, b);} ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ll mask){return __builtin_popcountll(mask);} int ctz(ll mask){return __builtin_ctzll(mask);} int logOf(ll mask){return __lg(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T& container, string separator = " ", string finish = "\n"){ for(auto item: container) cout << item << separator; cout << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } const ll INF = 1e18 + 69; struct Node{ ll ma; ll lazy_val, lazy_ass; Node(){ ma = lazy_val = 0; lazy_ass = -1; } }; struct SegmentTree{ int n; vector<Node> a; SegmentTree(int _n = 0){ n = _n; a.resize(n * 4 + 4); } void apply(int id, pair<ll, ll> val){ if (val.second != -1){ a[id].ma = a[id].lazy_ass = val.second; a[id].lazy_val = 0; } a[id].ma += val.first; a[id].lazy_val += val.first; } void down(int id){ pair<ll, ll> cur = make_pair(a[id].lazy_val, a[id].lazy_ass); if (cur.first == 0 && cur.second == -1) return; apply(id * 2, cur); apply(id * 2 + 1, cur); a[id].lazy_val = 0; a[id].lazy_ass = -1; } Node combine(Node a, Node b){ Node c; c.ma = max(a.ma, b.ma); return c; } ll get_idx(int i){ int id = 1; int l = 1, r = n; while(l < r){ down(id); int mid = (l + r) >> 1; if (i <= mid) { id = id * 2; r = mid; } else{ id = id * 2 + 1; l = mid + 1; } } return a[id].ma; } int find_bigger(ll x){ if (a[1].ma <= x) return n + 1; int id = 1; int l = 1, r = n; while(l < r){ down(id); int mid = (l + r) >> 1; if (a[id * 2].ma > x) { id = id * 2; r = mid; } else{ id = id * 2 + 1; l = mid + 1; } } return l; } void update_add(int u, int v, ll val, int l, int r, int id){ if (u <= l && r <= v){ apply(id, make_pair(val, -1)); return; } down(id); int mid = (l + r) >> 1; if (u <= mid) update_add(u, v, val, l, mid, id * 2); if (v > mid) update_add(u, v, val, mid + 1, r, id * 2 + 1); a[id] = combine(a[id * 2], a[id * 2 + 1]); } void update_add(int u, int v, ll val){ update_add(u, v, val, 1, n, 1); } void update_ass(int u, int v, ll val, int l, int r, int id){ if (u <= l && r <= v){ apply(id, make_pair(0, val)); return; } down(id); int mid = (l + r) >> 1; if (u <= mid) update_ass(u, v, val, l, mid, id * 2); if (v > mid) update_ass(u, v, val, mid + 1, r, id * 2 + 1); a[id] = combine(a[id * 2], a[id * 2 + 1]); } void update_ass(int u, int v, ll val){ update_ass(u, v, val, 1, n, 1); } }; const int N = 1e5 + 69, LOG_N = 17; int n, m, k; vector<int> graph[N]; vector<pair<int, int>> fruit[N]; SegmentTree st[LOG_N]; int sz[N]; void find_size(int u, int p){ sz[u] = 1; for(int v: graph[u]) if (v != p){ find_size(v, u); sz[u] += sz[v]; } } void dfs(int u, int p, int layer){ pair<int, int> heavy_node = {-1, -1}; for(int v: graph[u]) if (v != p){ maximize(heavy_node, make_pair(sz[v], v)); } if (heavy_node.first != -1){ dfs(heavy_node.second, u, layer); for(int v: graph[u]) if (v != p && v != heavy_node.second){ dfs(v, u, layer + 1); int i = 1; while(i <= k){ ll val = st[layer + 1].get_idx(i); int idx = st[layer + 1].find_bigger(val) - 1; st[layer + 1].update_ass(i, idx, 0); st[layer].update_add(i, idx, val); i = idx + 1; } } } for(pair<int, int> i: fruit[u]){ ll val = st[layer].get_idx(i.first) + i.second; int idx = st[layer].find_bigger(val); if (idx > i.first) st[layer].update_ass(i.first, idx - 1, val); } } void solve(){ cin >> n >> m >> k; for(int i = 2; i<= n; ++i){ int j; cin >> j; graph[i].push_back(j); graph[j].push_back(i); } for(int i = 0; i < m; ++i){ int v, d, w; cin >> v >> d >> w; fruit[v].push_back({d, w}); } for(int i = 1; i <= n; ++i) sort(ALL(fruit[i]), greater<pair<int, int>>()); for(int i = 0; i < LOG_N; ++i) st[i] = SegmentTree(k); find_size(1, 0); dfs(1, 0, 0); cout << st[0].get_idx(k) << "\n"; } int main(void){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); clock_t start = clock(); solve(); cerr << "Time elapsed: " << clock() - start << "ms!\n"; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...