Submission #1159453

#TimeUsernameProblemLanguageResultExecution timeMemory
1159453mertbbmMagic Tree (CEOI19_magictree)C++20
21 / 100
237 ms110448 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define ld long double #define show(x,y) cout << y << " " << #x << endl; #define show2(x,y,i,j) cout << y << " " << #x << " " << j << " " << #i << endl; #define show3(x,y,i,j,p,q) cout << y << " " << #x << " " << j << " " << #i << " " << q << " " << #p << endl; #define show4(x,y) for(auto it:y) cout << it << " "; cout << #x << endl; typedef pair<int,int>pii; typedef pair<pii,int>pi2; mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count()); inline int combine(int a, int b){ return max(a,b); } struct node{ int s,e,m; node *l,*r; int v; int lazyUpd; int lazySet; bool lset; node(int ss, int ee):s(ss),e(ee),m((s+e)>>1),v(0),lazyUpd(0),lazySet(0),lset(0){ if(s!=e){ l=new node(s,m); r=new node(m+1,e); } } void self_set(int x){ v=x; lazyUpd=0; lazySet=x; lset=true; } void self_add(int x){ if(lset){ self_set(lazySet+x); return; } v+=x; lazyUpd+=x; } void forceProp(){ if(s==e) return; if(lset){ l->self_set(lazySet); r->self_set(lazySet); lset=0; lazySet=0; } if(lazyUpd){ l->self_add(lazyUpd); r->self_add(lazyUpd); lazyUpd=0; } } void rangeUpd(int x, int y, int c){ if(x>y) return; if(x<=s&&y>=e){ self_add(c); return; } forceProp(); if(x<=m) l->rangeUpd(x,y,c); if(y>m) r->rangeUpd(x,y,c); v=combine(l->v,r->v); } void rangeSet(int x, int y, int c){ if(x>y) return; if(x<=s&&y>=e){ self_set(c); return; } forceProp(); if(x<=m) l->rangeSet(x,y,c); if(y>m) r->rangeSet(x,y,c); v=combine(l->v,r->v); } int query(int x, int y){ if(x>y) return 0; if(x<=s&&y>=e){ return v; } forceProp(); if(y<=m) return l->query(x,y); if(x>m) return r->query(x,y); return combine(l->query(x,m),r->query(m+1,y)); } int bs(int target){ if(s==e) return s; forceProp(); if(l->v<=target&&r->v<=target) return r->bs(target); else return l->bs(target); } }; int n,m,k; vector<int>adj[100005]; vector<pii>storage[100005]; int sz[100005]; int pp[100005]; void dfs(int index, int par){ if(adj[index].size()>=2&&adj[index][0]==par) swap(adj[index][0],adj[index][1]); sz[index]=1; for(auto &it:adj[index]){ if(it==par) continue; dfs(it,index); sz[index]+=sz[it]; pp[it]=index; if(sz[it]>sz[adj[index][0]]) swap(it,adj[index][0]); } } int hp[100005]; vector<int>uni[100005]; vector<pair<pii,int>>range[100005]; void hld(int index, int par){ for(auto it:adj[index]){ if(it==par) continue; if(it==adj[index][0]) hp[it]=hp[index]; else hp[it]=it; hld(it,index); if(uni[it].size()>uni[index].size()){ swap(uni[it],uni[index]); } for(auto it2:uni[it]){ uni[index].push_back(it2); } } for(auto it:storage[index]){ uni[index].push_back(it.first); } //show2(index,index,hp[index],hp[index]); if(hp[index]==index){ //show(index,index); sort(uni[index].begin(),uni[index].end()); uni[index].resize(unique(uni[index].begin(),uni[index].end())-uni[index].begin()); //show4(uni[index],uni[index]); vector<int>path; int cur=index; path.push_back(cur); while(1){ if(adj[cur][0]==pp[cur]) break; cur=adj[cur][0]; path.push_back(cur); } node st(0,sz[index]); reverse(path.begin(),path.end()); for(auto hold:path){ //combine first then query for(int y=1;y<(int)adj[hold].size();y++){ int a=adj[hold][y]; if(a==pp[hold]) continue; vector<pair<pii,int>>take; for(auto hold2:range[a]){ int lft=hold2.first.first; int rgt=hold2.first.second; int val=hold2.second; lft=lower_bound(uni[index].begin(),uni[index].end(),lft)-uni[index].begin(); rgt=lower_bound(uni[index].begin(),uni[index].end(),rgt)-uni[index].begin()-1; //take.push_back({{lft,rgt},val+st.query(0,lft-1)}); st.rangeUpd(lft,rgt,val); } for(auto it:take){ st.rangeUpd(it.first.first,it.first.second,it.second); } } //for(int y=0;y<sz[index];y++){ //cout << st.query(y,y) << " "; //} //cout << " st after merging " << hold << "\n"; //query vector<pii>take; for(auto item:storage[hold]){ int lft=lower_bound(uni[index].begin(),uni[index].end(),item.first)-uni[index].begin(); int val=st.query(0,lft)+item.second; take.push_back({lft,val}); } for(auto item:take){ //show2(item.first,item.first,item.second,item.second); int a=st.bs(item.second); //show(a,a); //cout << item.first << " " << a << " " << item.second << " rangeset\n"; st.rangeSet(item.first,a,item.second); } //for(int y=0;y<sz[index];y++){ //cout << st.query(y,y) << " "; //} //cout << " st after " << hold << "\n"; } //convert them to ranges for(int y=0;y<(int)uni[index].size();y++){ if(y==(int)uni[index].size()-1){ range[index].push_back(make_pair(make_pair(uni[index][y],(int)1e18),st.query(y,y))); } else range[index].push_back({{uni[index][y],uni[index][y+1]},st.query(y,y)}); } //for(auto it:range[index]){ //cout << it.first.first << " " << it.first.second << " " << it.second << "\n"; //} //cout << "\n\n"; } } void solve(){ cin >> n >> m >> k; int temp,temp2,temp3; for(int x=2;x<=n;x++){ cin >> temp; adj[temp].push_back(x); adj[x].push_back(temp); } for(int x=0;x<m;x++){ cin >> temp >> temp2 >> temp3; storage[temp].push_back({temp2,temp3}); } dfs(1,-1); hp[1]=1; hld(1,-1); int best=0; for(auto it:range[1]) best=max(best,it.second); cout << best; } int32_t main(){ ios::sync_with_stdio(0); cin.tie(0); //freopen("in.txt","r",stdin); //freopen("in.txt","w",stdout); int t=1; //cin >> t; while(t--){ solve(); } }
#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...