Submission #702919

#TimeUsernameProblemLanguageResultExecution timeMemory
702919jiahngMagic Tree (CEOI19_magictree)C++14
100 / 100
424 ms336680 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define int ll typedef pair<int,int> pi; typedef vector <int> vi; typedef vector <pi> vpi; typedef pair<pi, ll> pii; typedef set <ll> si; typedef long double ld; #define f first #define s second #define mp make_pair #define FOR(i,s,e) for(int i=s;i<=int(e);++i) #define DEC(i,s,e) for(int i=s;i>=int(e);--i) #define pb push_back #define all(x) (x).begin(), (x).end() #define lbd(x, y) lower_bound(all(x), y) #define ubd(x, y) upper_bound(all(x), y) #define aFOR(i,x) for (auto i: x) #define mem(x,i) memset(x,i,sizeof x) #define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define maxn 1000010 #define INF (ll)1e18 #define MOD 1000000007 typedef pair <vi, int> pvi; typedef pair <int,pi> ipi; typedef vector <pii> vpii; #define DEBUG 0 int TC,N,M,K; int D[maxn],W[maxn]; vi adj[maxn]; int p; struct node{ int s,e,m; node *l=nullptr,*r=nullptr; bool linit=0,rinit=0; int val = 0; node(int ss,int ee){ s = ss; e = ee; m = (s + e) / 2; } int qry(int a,int b){ if (a <= s && e <= b) return val; else if (a > e || s > b) return 0; else{ int ans = 0; if (linit) ans += l->qry(a,b); if (rinit) ans += r->qry(a,b); return ans; } } void upd(int p,int v){ val += v; assert(val >= 0); if (s == e) return; else if (p > m){ if (!rinit) r = new node(m+1,e); rinit = 1; r->upd(p,v); }else{ if (!linit) l = new node(s,m); linit = 1; l->upd(p,v); } } }*root[maxn]; multiset <pi> st[maxn]; void dfs(int x){ int mx = -1; aFOR(i, adj[x]){ dfs(i); if (mx == -1 || st[i].size() > st[mx].size()) mx = i; } if (mx != -1){ root[x] = root[mx]; st[x].swap(st[mx]); }else{ root[x] = new node(1,K); st[x].clear(); } aFOR(i,adj[x]) if (i != mx){ aFOR(j,st[i]){ root[x]->upd(j.f, j.s); st[x].insert(j); } } if (D[x] == 0) return; // no fruit //int v = root[x]->qry(1,D[x]) + W[x]; // update everything after D[x] by y -> max(y,v) //int pt = root[x]->bs(v); // earliest point where f(pt) >= v //int vpt = root[x]->qry(1, pt); root[x]->upd(D[x], W[x]); // shift up first, then flatten st[x].insert(pi(D[x], W[x])); if (DEBUG){ cout << x << ' ' << '\n'; aFOR(i, st[x]) cout << i.f << ' ' << i.s << '\n'; cout << "\n\n"; } int cur = W[x]; auto it = st[x].upper_bound(pi(D[x], INF)); while (cur > 0){ if (it == st[x].end()) break; if (cur >= it->s){ cur -= it->s; root[x]->upd(it->f, -it->s); }else{ root[x]->upd(it->f, -cur); pi tmp = *it; st[x].insert(pi(tmp.f, tmp.s-cur)); cur = 0; } st[x].erase(it++); } /* int sm = 0; auto it = st[x].begin(); while (it != st[x].end()){ int cur = it->f; while (it != st[x].end() && it->f == cur){ sm += it->s; it++; } assert(sm == root[x]->qry(1,cur)); } */ } void solve(){ cin >> N >> M >> K; FOR(i,2,N){ cin >> p; adj[p].pb(i); } int v,d,w; FOR(i,1,M){ cin >> v >> d >> w; D[v] = d; W[v] = w; } dfs(1); cout << root[1]->val; } int32_t main(){ fast; 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...