제출 #39503

#제출 시각아이디문제언어결과실행 시간메모리
3950314kg공장들 (JOI14_factories)C++11
100 / 100
4099 ms144720 KiB
#include "factories.h"
#include <algorithm>
#include <vector>
#define N 500001
#define LL long long
#define INF 999999999999999999
#define min2(x,y) (x<y?x:y)

using namespace std;
int n, t[N], tree_up[N][20], p[20];
int tree_lev[N], tree_e[N];
LL deep[N];
vector<pair<int, int> > r[N];

int dfs_lev, q_len, dfs_num;
LL out;
pair<int, int> q[N * 3];

void dfs(int x, int up, LL _deep, int _t) {
	tree_lev[x] = ++dfs_lev;
	deep[dfs_lev] = _deep, t[dfs_lev] = _t;

	tree_up[dfs_lev][0] = tree_lev[up];
	for (int i = 1; i < 20; i++)
		tree_up[dfs_lev][i] = tree_up[tree_up[dfs_lev][i - 1]][i - 1];

	for (auto i : r[x])
		if (i.first != up) dfs(i.first, x, _deep + (LL)i.second, _t + 1);
	tree_e[tree_lev[x]] = dfs_lev;
}
void Init(int _n, int *a, int *b, int *d) {
	n = _n;
	for (int i = 0; i < n - 1; i++) {
		r[a[i] + 1].push_back({ b[i] + 1,d[i] });
		r[b[i] + 1].push_back({ a[i] + 1,d[i] });
	} dfs(1, 0, 0, 1);

	p[0] = 1;
	for (int i = 1; i < 20; i++) p[i] = p[i - 1] * 2;
}

int lca(int x, int y) {
	for (int i = 19; i >= 0; i--)
		if (t[x] - p[i] >= t[y]) x = tree_up[x][i];
	for (int i = 19; i >= 0; i--)
		if (t[y] - p[i] >= t[x]) y = tree_up[y][i];
	for (int i = 19; i >= 0; i--)
		if (tree_up[x][i] != tree_up[y][i])
			x = tree_up[x][i], y = tree_up[y][i];

	if (x != y) x = tree_up[x][0];
	return x;
}
pair<LL,LL> dfs2() {
	int lev = q[dfs_num].first;
	bool type[3] = { 0 };
	LL MIN1 = INF, MIN2 = INF;

	type[q[dfs_num].second] = true, dfs_num++;
	while (q[dfs_num].first == lev) type[q[dfs_num].second] = true, dfs_num++;

	while (tree_e[lev] >= q[dfs_num].first) {
		pair<LL, LL> temp = dfs2();
		MIN1 = min2(MIN1, temp.first), MIN2 = min2(MIN2, temp.second);
	}
	if (type[1]) MIN1 = min2(MIN1, deep[lev]);
	if (type[2]) MIN2 = min2(MIN2, deep[lev]);
	out = min2(out, MIN1 + MIN2 - deep[lev] * 2);
	return { MIN1,MIN2 };
}
LL Query(int a_len, int a[], int b_len, int b[]) {
	int temp;

	q_len = 0, out = INF;
	for (int i = 0; i < a_len; i++) {
		temp = tree_lev[a[i] + 1];
		q[++q_len] = { temp,1 };
	}
	for (int i = 0; i < b_len; i++) {
		temp = tree_lev[b[i] + 1];
		q[++q_len] = { temp,2 };
	}
	sort(q + 1, q + q_len + 1), temp = q_len;
	for (int i = 1; i < temp; i++) q[++q_len] = { lca(q[i].first, q[i + 1].first),0 };
	sort(q + 1, q + q_len + 1), q[q_len + 1] = { n + 1, 0 };

	dfs_num=1, dfs2();

	return out;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...