Submission #1315102

#TimeUsernameProblemLanguageResultExecution timeMemory
1315102vlomaczkDesignated Cities (JOI19_designated_cities)C++20
0 / 100
566 ms60336 KiB
#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) {
		x+=base;
		T[x].second = val;
		x/=2;
		while(x>0) {
			T[x] = max(T[x+x],T[x+x+1]);
			x/=2;
		}
	}

	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) {
		base = 1<<19;
		T.assign(2*base,{0,0});
		L.assign(2*base,0);
	}

} 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+1)/2) return find_centroid(u,ts);
		} else {
			if(sajz[u] > (ts+1)/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);
	ll cnt = 0;
	ll res = only[v];
	// cout << st.T[1].first << " " << st.T[1].second << "\n";
	// return;
	while(st.T[1].first > 0) {
		cnt++;
		ll x = st.T[1].second;
		while(cost[x] > 0) {
			st.update(1,0,st.base-1,pre[x],post[x],-cost[x]);
			res += cost[x];
			cost[x]=0;
			x=par[x];
		}
		if(cnt > 1) ans[cnt] = max(ans[cnt], res);
		ans[cnt+1] = max(ans[cnt], res);
	}
	stack<pair<int,int>> S;
	S.push({v,v});
	while(S.size()) {
		auto[x,p] = S.top(); S.pop();
		st.ustaw(pre[x],0);
		st.ustaw(post[x],0);
		pre[v]=post[v]=cost[v]=0;
		for(auto[u,k] : g[x]) {
			if(u==p || is_off[u]) continue;
			S.push({u,x});
		}
	}
	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]);
	}
	centroid_decomposition(1);
	ll q; cin >> q;
	while(q--) {
		ll x; cin >> x;
		cout << sum - ans[x] << "\n";
	}

	return 0;
}
#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...