Submission #1312739

#TimeUsernameProblemLanguageResultExecution timeMemory
1312739crispxxFactories (JOI14_factories)C++20
100 / 100
2500 ms159868 KiB
#include "factories.h"

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

const ll inf = 1e18;

vector<vector<array<ll, 2>>> adj;

vector<vector<int>> jmp;

vector<int> tin, tout;

vector<bool> sn, tn;

vector<ll> d, mxs, mxt, rs, rt;

bool cmp(int u, int v) {
	return tin[u] < tin[v];
}

bool upper(int u, int v) {
	return tin[v] >= tin[u] && tout[v] <= tout[u];
}

bool chmin(ll &a, const ll &b) {
	return a > b ? a = b, true : false;
}

bool chmax(ll &a, const ll &b) {
	return a < b ? a = b, true : false;
}

int lca(int u, int v) {
	if(upper(u, v)) return u;
	
	for(int i = 19; i >= 0; i--) {
		if(!upper(jmp[u][i], v)) {
			u = jmp[u][i];
		}
	}
	
	return jmp[u][0];
}

void Init(int n, int a[], int b[], int D[]) {
	adj.resize(n);
	jmp.resize(n);
	sn.resize(n);
	tn.resize(n);
	mxs.resize(n);
	mxt.resize(n);
	rs.resize(n);
	rt.resize(n);
	tin.resize(n);
	tout.resize(n);
	d.resize(n);
	
	for(int i = 0; i < n; i++) {
		jmp[i].resize(20);
	}
	
	for(int i = 0; i < n - 1; i++) {
		adj[a[i]].push_back({b[i], D[i]});
		adj[b[i]].push_back({a[i], D[i]});
	}
	
	int timer = 0;
	
	auto dfs = [&](auto &&self, int v, int p) -> void {
		jmp[v][0] = p;
		
		for(int i = 1; i < 20; i++) {
			jmp[v][i] = jmp[ jmp[v][i - 1] ][i - 1];
		}
		
		tin[v] = ++timer;
		
		for(auto [to, c] : adj[v]) {
			if(to == p) continue;
			
			d[to] = d[v] + c;
			
			self(self, to, v);
		}
		
		tout[v] = timer;
	};
	
	dfs(dfs, 0, 0);
	
	for(int i = 0; i < n; i++) {
		adj[i].clear();
	}
}

long long Query(int s, int x[], int t, int y[]) {
	vector<int> ver;
	
	for(int i = 0; i < s; i++) {
		ver.push_back(x[i]);
	}
	
	for(int i = 0; i < t; i++) {
		ver.push_back(y[i]);
	}
	
	sort(ver.begin(), ver.end(), cmp);
	
	for(int i = 0; i + 1 < s + t; i++) {
		ver.push_back( lca(ver[i], ver[i + 1]) );
	}
	
	sort(ver.begin(), ver.end(), cmp);
	ver.erase(unique(ver.begin(), ver.end()), ver.end());
	
	for(auto &v : ver) {
		adj[v].clear();
		sn[v] = tn[v] = false;
		mxs[v] = mxt[v] = rs[v] = rt[v] = inf;
	}
	
	for(int i = 0; i < s; i++) {
		sn[x[i]] = true;
	}
	
	for(int i = 0; i < t; i++) {
		tn[y[i]] = true;
	}
	
	stack<int> st;
	
	for(int i = 0; i < (int)ver.size(); i++) {
		while(!st.empty() && !upper(st.top(), ver[i])) {
			st.pop();
		}
		
		if(!st.empty()) {
			adj[st.top()].push_back({ver[i], d[ver[i]] - d[st.top()]});
		}
		
		st.push(ver[i]);
	}
	
	// cout << "edges: " << '\n';
	
	// for(auto v : ver) {
		// for(auto [to, c] : adj[v]) {
			// cout << v << ' ' << to << ' ' << c << '\n';
		// }
	// }
	
	{
		auto dfs = [&](auto &&self, int v) -> void {
			if(sn[v]) mxs[v] = d[v];
			if(tn[v]) mxt[v] = d[v];
			
			for(auto [to, c] : adj[v]) {
				self(self, to);
				
				chmin(mxs[v], mxs[to]);
				chmin(mxt[v], mxt[to]);
			}
		};
		
		dfs(dfs, ver[0]);
	}
	
	ll ans = inf;
	
	{
		auto dfs = [&](auto &&self, int v) -> void {
			if(sn[v]) {
				chmin(ans, min(rt[v], mxt[v] - d[v]));
			}
			
			if(tn[v]) {
				chmin(ans, min(rs[v], mxs[v] - d[v]));
			}
			
			int m = adj[v].size();
			
			vector<array<ll, 2>> suf(m + 1, {inf, inf});
			
			for(int i = m - 1; i >= 0; i--) {
				auto [to, c] = adj[v][i];
				suf[i][0] = min(suf[i + 1][0], mxs[to]);
				suf[i][1] = min(suf[i + 1][1], mxt[to]);
			}
			
			array<ll, 2> pref{inf, inf};
			
			for(int i = 0; i < m; i++) {
				auto [to, c] = adj[v][i];
				rs[to] = c + min({rs[v], suf[i + 1][0] - d[v], pref[0] - d[v]});
				rt[to] = c + min({rt[v], suf[i + 1][1] - d[v], pref[1] - d[v]});
				chmin(pref[0], mxs[to]);
				chmin(pref[1], mxt[to]);
				self(self, to);
			}
		};
		
		dfs(dfs, ver[0]);
	}
	
	return ans;
}































#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...