Submission #577932

#TimeUsernameProblemLanguageResultExecution timeMemory
577932M_WFactories (JOI14_factories)C++17
0 / 100
22 ms25044 KiB
#include <bits/stdc++.h>
#define ii pair<int, long long>
using namespace std;
int up[21][500001], lg, timer = 0;
int tin[500001], tout[500001]; 
long long dist[500001];
vector<ii> adj[500001];

// LCA stuff

void process_lca(int a, int p){
	tin[a] = timer++;
	for(int i = 1; i <= lg; i++){
		up[a][i] = up[up[a][i - 1]][i - 1];
	}
	
	for(auto [x, w] : adj[a]){
		if(x == p) continue;
		dist[x] = dist[a] + w;
		process_lca(x, a);
	}
	tout[a] = timer++;
}

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

int lca(int u, int v){
	if(is_an(v, u)) return v;
	for(int i = lg; i >= 0; i--){
		if(!is_an(u, v)) u = up[u][i];
	}
	return up[u][0];
}

long long get_dist(int u, int v){
	int lca_uv = lca(u, v);
	return - (dist[lca_uv] << 1) + (dist[u] + dist[v]);
}

// Centroid stuff

bool blocked[500001];
int sz[500001], split_node;

int calc_subtree(int a, int p){
	sz[a] = 1;
	for(auto [x, w] : adj[a]){
		if(x == p || blocked[x]) continue;
		sz[a] += calc_subtree(x, a);
	}
	return sz[a];
}

bool get_split(int a, int p, int rt){
	int msz = sz[rt] - sz[a];
	for(auto [x, w] : adj[a]){
		if(x == p || blocked[x]) continue;
		msz = max(msz, sz[x]);
		if(get_split(x, a, rt)) return true;
	}
	if(msz <= sz[rt] >> 1){
		split_node = a;
		return true;
	}
	return false;
}

int pa[500001];

void build_tree(int a, int p){
	calc_subtree(a, p);
	get_split(a, p, a);
	
	pa[split_node] = p;
	blocked[split_node] = true;
	for(auto [x, w] : adj[split_node]){
		if(blocked[x]) continue;
		build_tree(x, split_node);
	}
}

// Actual Problem

int bk[500001], book = 1;
long long d[500001];

void update(int u){
	int tmp_u = u;
	while(u != -1){
		if(bk[u] < book) d[u] = get_dist(tmp_u, u);
		else d[u] = min(d[u], get_dist(tmp_u, u));
		bk[u] = book;
		u = pa[u];
	}
}

long long query(int v){
	int tmp_v = v; long long ret = LLONG_MAX;
	while(v != -1){
		if(bk[v] == book) ret = min(ret, d[v] + get_dist(tmp_v, v));
		v = pa[v];
	}
	return ret;
}

// Functions

void Init(int N, int* A, int* B, int* D){
	lg = int(ceil(log2(N)));
	
	for(int i = 0; i < N - 1; i++){
		adj[A[i]].push_back({B[i], D[i] * 1ll});
		adj[B[i]].push_back({A[i], D[i] * 1ll});
	}
	process_lca(0, -1);
	build_tree(0, -1);
}

long long Query(int S, int* X, int T, int* Y){
	long long ans = LLONG_MAX;
	for(int i = 0; i < S; i++) update(X[i]);
	for(int j = 0; j < T; j++) ans = min(ans, query(Y[j]));
	book++;
	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...