Submission #1128504

#TimeUsernameProblemLanguageResultExecution timeMemory
1128504NonozeFactories (JOI14_factories)C++20
33 / 100
8093 ms225472 KiB
#include "factories.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define cmin(a, b) a = min(a, b)
const int inf = 1e18;

const signed LOG=18;


signed n;
vector<pair<signed, signed>> adj[500005];
pair<signed, int> up[500005][LOG];
signed depth[500005];

void dfsinit(signed u, signed p) {
	for (auto [v, w]: adj[u]) if (v!=p) {
		up[v][0]={u, w};
		for (int i=1; i<LOG; i++) {
			if (up[v][i-1].fi==-1) break;
			up[v][i]=up[up[v][i-1].fi][i-1];
			up[v][i].se+=up[v][i-1].se;
		}
		depth[v]=depth[u]+1;
		dfsinit(v, u);
	}
}

int dist(signed a, signed b) {
	if (a==b) return 0;
	if (depth[a]<depth[b]) swap(a, b);
	int ans=0;
	signed k=depth[a]-depth[b];
	for (signed i=0; i<LOG&&k; i++) {
		if (k&(1<<i)) ans+=up[a][i].se, a=up[a][i].fi, k^=1<<i;
	}
	if (a==b) return ans;
	for (signed i=31-__builtin_clz(depth[a]); i>=0; i--) if (up[a][i].fi!=up[b][i].fi) {
		ans+=up[a][i].se+up[b][i].se;
		a=up[a][i].fi, b=up[b][i].fi;
	}
	return ans+up[a][0].se+up[b][0].se;
}


signed sz[500005], par[500005];
bool centro[500005];

void dfs(signed u, signed p) {
	sz[u]=1;
	for (auto [v, w]: adj[u]) if (v!=p && !centro[v]) {
		dfs(v, u);
		sz[u]+=sz[v];
	}
}

signed centroid(signed u, signed p, signed obj) {
	for (auto [v, w]: adj[u]) if (v!=p && !centro[v]) {
		if (sz[v]*2>=obj) return centroid(v, u, obj);
	}
	return u;
}

signed decompose(signed u, signed p) {
	if (centro[u]) return u;
	dfs(u, u);
	signed c=centroid(u, u, sz[u]); centro[c]=1;
	par[c]=p;
	for (auto [v, w]: adj[c]) if (!centro[v]) decompose(v, c);
	return c;
}

int distres[500005];

void Init(signed N, signed A[], signed B[], signed D[]) {
	n=N;
	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]});
		distres[i]=inf, centro[i]=0;
	}
	distres[n-1]=inf, centro[n-1]=0;
	dfsinit(0, 0);
	decompose(0, -1);
}

int Query(signed S, signed X[], signed T, signed Y[]) {
	int ans=inf;
	for (int i=0; i<S; i++) {
		signed act=X[i];
		while (act!=-1) {
			cmin(distres[act], dist(act, X[i]));
			act=par[act];
		}
	}
	for (int i=0; i<T; i++) {
		signed act=Y[i];
		while (act!=-1) {
			cmin(ans, distres[act]+dist(act, Y[i]));
			act=par[act];
		}
	}
	for (int i=0; i<S; i++) {
		signed act=X[i];
		while (act!=-1) {
			distres[act]=inf;
			act=par[act];
		}
	}
	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...