#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll M = 200'010;
vector<ll> ans(M, 0), only(M), depth(M), sajz(M), par(M), is_off(M), cost(M), pre(M), post(M);
vector<vector<pair<ll, ll>>> g(M);
ll added = 0,nxt;
struct SegTree {
ll base=1;
vector<pair<ll,ll>> T;
vector<ll> L;
void push(ll v, ll l, ll r) {
if(L[v]==0 || v >= base) return;
T[l].first += L[v];
T[r].first += L[v];
L[l] += L[v];
L[r] += L[v];
L[v] = 0;
}
void ustaw(ll x, ll val) {
T[x+base].second = val;
}
void update(ll v, ll a, ll b, ll p, ll k, ll val) {
if(b < p || k < a) return;
if(p<=a && b<=k) {
T[v].first += val;
L[v] += val;
return;
}
ll l=2*v; ll r=2*v+1; ll mid=(a+b)/2;
push(v,l,r);
update(l,a,mid,p,k,val);
update(r,mid+1,b,p,k,val);
T[v] = max(T[l], T[r]);
}
SegTree(ll n) {
while(base<=n) base*=2;
T.resize(2*base);
L.resize(2*base);
}
} st(2*M);
void only_dfs(ll v, ll p) {
depth[v] = depth[p] + 1;
for(auto[u,k] : g[v]) {
if(u==p) continue;
only[u] += only[v];
only_dfs(u,v);
}
}
void sajz_dfs(ll v, ll p) {
sajz[v] = 1;
par[v] = p;
for(auto[u,k] : g[v]) {
if(u==p || is_off[u]) continue;
sajz_dfs(u,v);
sajz[v] += sajz[u];
}
}
ll find_centroid(ll v, ll ts) {
for(auto[u,k] : g[v]) {
if(is_off[u]) continue;
if(u==par[v]) {
if(ts-sajz[v] > ts/2) return find_centroid(u,ts);
} else {
if(sajz[u] > ts/2) return find_centroid(u,ts);
}
}
return v;
}
void pre_dfs(ll v, ll p) {
for(auto[u,k] : g[v]) if(u==p) cost[v] = k;
pre[v] = ++nxt;
st.ustaw(pre[v], v);
for(auto[u,k] : g[v]) {
if(u==p || is_off[u]) continue;
pre_dfs(u,v);
}
post[v] = ++nxt;
st.ustaw(post[v],v);
st.update(1,0,st.base-1,pre[v],post[v],cost[v]);
}
void centroid_decomposition(ll v) {
sajz_dfs(v,v);
v = find_centroid(v,sajz[v]);
sajz_dfs(v,v);
nxt=0;
cost[v] = 0;
pre_dfs(v,v);
for(ll i=0; i<nxt; ++i) st.update(1,0,st.base-1,i,i,0);
ll cnt = 0;
ll res = only[v];
while(st.T[1].first > 0) {
cnt++;
ll x = st.T[1].second;
res += st.T[1].first;
while(cost[x] > 0) {
st.update(1,0,st.base-1,pre[x],post[x],-cost[x]);
cost[x]=0;
x=par[x];
}
if(cnt > 1) ans[cnt] = max(ans[cnt], res);
ans[cnt+1] = max(ans[cnt], res);
}
is_off[v] = 1;
for(auto[u,k] : g[v]) {
if(is_off[u]) continue;
centroid_decomposition(u);
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll n;
cin >> n;
ll sum = 0;
vector<pair<pair<ll, ll>, pair<ll, ll>>> edges;
for(ll i=1; i<n; ++i) {
ll a,b,c,d;
cin >> a >> b >> c >> d;
swap(c,d);
g[a].push_back({b,c});
g[b].push_back({a,d});
edges.push_back({{a,c},{b,d}});
sum += c + d;
}
only_dfs(1,0);
for(auto[x,y] : edges) {
if(depth[y.first] > depth[x.first]) swap(x,y);
auto[a,c] = x;
auto[b,d] = y;
only[a] += c-d;
added += d;
}
only_dfs(1,0);
for(ll i=1; i<=n; ++i) {
only[i] += added;
ans[1] = max(ans[1], only[i]);
}
// for(ll i=1; i<=n; ++i) cout << only[i] << " "; cout << "\n";
// cout << sum << "\n";
// cout << "Xd\n"; return 0;
// centroid_decomposition(1);
ll q; cin >> q;
while(q--) {
ll x; cin >> x;
cout << sum - ans[x] << "\n";
}
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |