제출 #1302074

#제출 시각아이디문제언어결과실행 시간메모리
1302074regulardude6Tree (IOI24_tree)C++20
100 / 100
251 ms90900 KiB
#include "tree.h" #include <bits/stdc++.h> using namespace std; using ll = long long; static const ll INF = (ll)4e18; struct Seg { struct Node { int k; ll sum; ll mnw; int mni; }; int n; vector<Node> st; vector<char> lz; Node neu() { return {0, 0, INF, -1}; } Node merge(const Node& a, const Node& b) { Node r; r.k = a.k + b.k; r.sum = a.sum + b.sum; if (a.mnw <= b.mnw) { r.mnw = a.mnw; r.mni = a.mni; } else { r.mnw = b.mnw; r.mni = b.mni; } return r; } Seg(int n=0): n(n) { st.assign(4*n+5, neu()); lz.assign(4*n+5, 0); } void apply_del(int p) { st[p] = neu(); lz[p] = 1; } void push(int p) { if (!lz[p]) return; apply_del(p<<1); apply_del(p<<1|1); lz[p] = 0; } void build(int p, int l, int r, const vector<int>& pos2v, const vector<ll>& W, const vector<char>& isLeaf) { if (l == r) { int v = pos2v[l]; if (isLeaf[v]) st[p] = {1, W[v], INF, -1}; else st[p] = {0, 0, W[v], v}; return; } int m = (l+r)>>1; build(p<<1, l, m, pos2v, W, isLeaf); build(p<<1|1, m+1, r, pos2v, W, isLeaf); st[p] = merge(st[p<<1], st[p<<1|1]); } Node query(int p, int l, int r, int ql, int qr) { if (qr < l || r < ql) return neu(); if (ql <= l && r <= qr) return st[p]; push(p); int m = (l+r)>>1; return merge(query(p<<1, l, m, ql, qr), query(p<<1|1, m+1, r, ql, qr)); } void delRange(int p, int l, int r, int ql, int qr) { if (qr < l || r < ql) return; if (ql <= l && r <= qr) { apply_del(p); return; } push(p); int m = (l+r)>>1; delRange(p<<1, l, m, ql, qr); delRange(p<<1|1, m+1, r, ql, qr); st[p] = merge(st[p<<1], st[p<<1|1]); } void setLeafZero(int p, int l, int r, int idx) { if (l == r) { st[p] = {1, 0, INF, -1}; lz[p] = 0; return; } push(p); int m = (l+r)>>1; if (idx <= m) setLeafZero(p<<1, l, m, idx); else setLeafZero(p<<1|1, m+1, r, idx); st[p] = merge(st[p<<1], st[p<<1|1]); } }; static int N; static vector<int> P; static vector<ll> W; static vector<vector<int>> ch; static vector<char> isLeaf; static ll leafSum; static int totalLeaves; static vector<int> tin, tout, pos2v; static int timer_; static Seg seg; static vector<ll> addW, addKW, sufW, sufKW, Acoef, Bcoef; static void dfs(int v) { tin[v] = timer_; pos2v[timer_] = v; timer_++; for (int u : ch[v]) dfs(u); tout[v] = timer_ - 1; } static void solve_sub(int root, ll offset) { while (true) { auto got = seg.query(1, 0, N-1, tin[root], tout[root]); if (got.mnw >= INF/2) return; int k = got.k; int v = got.mni; ll wprime = got.mnw - offset; if (wprime < 0) wprime = 0; addW[k] += wprime; addKW[k] += wprime * (ll)k; ll newOffset = offset + wprime; for (int u : ch[v]) { solve_sub(u, newOffset); seg.delRange(1, 0, N-1, tin[u], tout[u]); } seg.setLeafZero(1, 0, N-1, tin[v]); offset = newOffset; } } void init(vector<int> _P, vector<int> _W) { P = _P; N = (int)P.size(); W.assign(N, 0); for (int i = 0; i < N; i++) W[i] = (ll)_W[i]; ch.assign(N, {}); int root = 0; for (int i = 0; i < N; i++) { if (P[i] == -1) root = i; else ch[P[i]].push_back(i); } isLeaf.assign(N, 0); leafSum = 0; totalLeaves = 0; for (int i = 0; i < N; i++) { if (ch[i].empty()) { isLeaf[i] = 1; leafSum += W[i]; totalLeaves++; } } tin.assign(N, 0); tout.assign(N, 0); pos2v.assign(N, 0); timer_ = 0; dfs(root); seg = Seg(N); seg.build(1, 0, N-1, pos2v, W, isLeaf); addW.assign(N+2, 0); addKW.assign(N+2, 0); solve_sub(root, 0); sufW.assign(N+3, 0); sufKW.assign(N+3, 0); for (int k = N; k >= 0; k--) { sufW[k] = sufW[k+1] + addW[k]; sufKW[k] = sufKW[k+1] + addKW[k]; } Acoef.assign(N+2, 0); Bcoef.assign(N+2, 0); for (int t = 0; t <= N; t++) { Acoef[t] = leafSum + sufKW[t+1]; Bcoef[t] = -sufW[t+1]; } } long long query(int L, int R) { ll LL = (ll)L, RR = (ll)R; int t = (int)(RR / LL); if (t > N) t = N; return Acoef[t] * LL + Bcoef[t] * RR; }
#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...