Submission #1049131

#TimeUsernameProblemLanguageResultExecution timeMemory
1049131antonMagic Tree (CEOI19_magictree)C++17
100 / 100
936 ms566080 KiB
#include<bits/stdc++.h> using namespace std; #define int long long #define pii pair<int, int> int N, M, K; const int INF= 1e18; struct Fruit{ int pos = -1, t, w; Fruit(){}; Fruit(int _pos, int _t, int _w){ pos = _pos; t= _t; w =_w; } }; struct Node{ int l = 0, r = 0; int lazy = 0, v = 0; int sz = 0; Node(int _l, int _r){ l = _l; r= _r; } }; struct HollowTree{ vector<Node> tr; HollowTree(){ tr.resize(2, Node(0, 0)); } Node get_node(int l, int r){ Node res= Node(l, r); res.v = max(tr[l].v, tr[r].v); return res; } void upd(int i){ tr[i].v = max(tr[tr[i].l].v, tr[tr[i].r].v) + tr[i].lazy; tr[i].sz = tr[tr[i].l].sz + tr[tr[i].r].sz; } void propagate(int t){ if(tr[t].l == 0){ tr[t].l = tr.size(); tr.push_back(Node(0, 0)); } if(tr[t].r == 0){ tr[t].r = tr.size(); tr.push_back(Node(0, 0)); } } void insert(int pos, int v, int lt, int rt, int t){ if(lt == rt){ tr[t].lazy = v; tr[t].v = v; tr[t].sz = 1; } else{ propagate(t); int mid = (lt+rt)/2; if(pos<=mid){ insert(pos, v-tr[t].lazy, lt, mid, tr[t].l); } else{ insert(pos, v-tr[t].lazy, mid+1, rt, tr[t].r); } upd(t); } } void add(int l, int r, int v, int lt, int rt, int t){ if(l<= lt && rt <= r){ tr[t].lazy +=v; tr[t].v+=v; } else if(r<lt || rt <l){ return; } else{ int mid = (lt+rt)/2; propagate(t); add(l, r, v, lt, mid, tr[t].l); add(l, r, v, mid+1, rt, tr[t].r); upd(t); } } int get(int l, int r, int lt, int rt, int t){ if(l<= lt && rt <= r){ return tr[t].v; } else if(r<lt || rt <l){ return 0; } else{ int mid = (lt+rt)/2; propagate(t); return max(get(l, r, lt, mid, tr[t].l), get(l, r, mid+1, rt, tr[t].r)) + tr[t].lazy; } } void iterate(vector<pii>& res,int lazy, int lt, int rt, int t){ if(lt == rt){ if(res.size()==0 || tr[t].v+ lazy>= res.back().second){ res.push_back({lt, tr[t].v+ lazy}); } } else{ int mid =(lt+rt)/2; propagate(t); if(tr[tr[t].l].sz>0){ iterate(res, lazy +tr[t].lazy,lt, mid, tr[t].l); } if(tr[tr[t].r].sz>0){ iterate(res,lazy +tr[t].lazy, mid+1, rt, tr[t].r); } } } void merge(HollowTree& rh){ vector<pii> rh_e; rh.iterate(rh_e, 0, 0, INF,1); int prev= 0; for(auto e: rh_e){ int max_before = get(0, e.first, 0, INF, 1); insert(e.first, max_before, 0, INF, 1); prev = e.second; } prev= 0; int prev_pos = 0; for(auto e: rh_e){ add(prev_pos, e.first-1, prev, 0, INF, 1); prev_pos = e.first; prev= e.second; } add(prev_pos, INF, prev, 0, INF, 1); } void display(){ vector<pii> res; iterate(res, 0, 0, INF, 1); for(auto e: res){ cout<<e.first<<" "<<e.second<<endl; } } }; vector<Fruit> fr; vector<Fruit> vertex_fruit; vector<int> anc; vector<vector<int>> ch; vector<vector<int>> fruit_ch; void dfs2(int u, int fruit_anc){ if(vertex_fruit[u].pos != -1){ fruit_ch[fruit_anc].push_back(u); fruit_anc = u; } for(auto e: ch[u]){ dfs2(e, fruit_anc); } } int find_pos(vector<int> &v, int e){ int cur =0; for(int step = (1<<20); step>=1; step/=2){ if(cur + step<v.size()){ if(v[cur+step]<=e){ cur+=step; } } } return cur; } vector<HollowTree> trees; void dfs(int u){ for(auto e: fruit_ch[u]){ dfs(e); if(trees[e].tr.size()>trees[u].tr.size()){ swap(trees[e], trees[u]); } trees[u].merge(trees[e]); } if(vertex_fruit[u].pos != -1){ int max_before = trees[u].get(0, vertex_fruit[u].t, 0, INF, 1); trees[u].insert(vertex_fruit[u].t, max_before+vertex_fruit[u].w, 0, INF, 1); } //cout<<"tree "<<u+1<<endl; //trees[u].display(); } signed main(){ cin.tie(NULL); ios_base::sync_with_stdio(false); cin>>N>>M>>K; trees.resize(N); vertex_fruit.resize(N, Fruit(-1, -1, -1)); ch.resize(N); fruit_ch.resize(N); anc.resize(N); for(int i= 1; i<N; i++){ cin>>anc[i]; anc[i]--; ch[anc[i]].push_back(i); } vector<int> times; for(int i = 0; i<M; i++){ int v, d, w; cin>>v>>d>>w; v--; times.push_back(d); fr.push_back(Fruit(v, d, w)); } sort(times.begin(), times.end()); for(Fruit& f: fr){ f.t = find_pos(times, f.t); vertex_fruit[f.pos] = f; } K = min(K, M); dfs2(0, 0); dfs(0); cout<<trees[0].get(0, INF, 0, INF, 1)<<endl; }

Compilation message (stderr)

magictree.cpp: In function 'long long int find_pos(std::vector<long long int>&, long long int)':
magictree.cpp:175:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  175 |         if(cur + step<v.size()){
      |            ~~~~~~~~~~^~~~~~~~~
#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...