QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#864898#5418. Color the Treelc20110802ML 2ms18148kbC++142.6kb2025-01-21 10:54:222025-01-21 10:54:32

Judging History

你现在查看的是最新测评结果

  • [2025-01-21 10:54:32]
  • 评测
  • 测评结果:ML
  • 用时:2ms
  • 内存:18148kb
  • [2025-01-21 10:54:22]
  • 提交

answer

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

const int N = 1e5 + 10;
int n, dfncnt, rt;
int a[N], dfn[N], dep[N], lg2[N], dp[N];
vector<int> g[N], h[N], vtp, vt[N];
int stc[N][18], fa[N][18];

void init(){
	dfncnt = 0;
	vtp.clear();
	for(int i = 0; i <= n; i++){
		g[i].clear(), h[i].clear(), vt[i].clear();
		dep[i] = dfn[i] = dp[i] = a[i] = 0;
		for(int j = 0; j < 18; j++) {
			stc[i][j] = 1e18;
			fa[i][j] = 0;
		}
	}
	n = rt = 0;
	return ;
}

inline int query_min(int l, int r){
	l++, r++;
	int T = lg2[r - l + 1];
	return min(stc[l][T], stc[r - (1 << T) + 1][T]);
}

void dfs(int u, int pre){
	dfn[u] = ++dfncnt;
	dep[u] = dep[pre] + 1; h[dep[u]].push_back(u);
	fa[u][0] = pre; for(int i = 1; i <= 20; i++)
		fa[u][i] = fa[fa[u][i - 1]][i - 1];
	for(int v : g[u]) if(v != pre)
		dfs(v, u);
	return ;
}
inline int lca(int x, int y){
	if(dep[x] < dep[y]) swap(x, y);
	for(int i = 17; i >= 0; i--)
		if(dep[fa[x][i]] >= dep[y])
			x = fa[x][i];
	if(x == y) return x;
	for(int i = 17; i >= 0; i--)
		if(fa[x][i] != fa[y][i])
			x = fa[x][i], y = fa[y][i];
	return fa[x][0];
}
inline void build_virtual_tree(vector<int> imp){
	sort(imp.begin(), imp.end(), [](int _x, int _y){return dfn[_x] < dfn[_y];});
	vtp.clear();
	for(int i = 0; i < imp.size() - 1; i++)
		vtp.push_back(imp[i]), vtp.push_back(lca(imp[i], imp[i + 1]));
	vtp.push_back(imp.back());
	sort(vtp.begin(), vtp.end(), [](int _x, int _y){return dfn[_x] < dfn[_y];});
	int len = unique(vtp.begin(), vtp.end()) - vtp.begin();
	for(int i : vtp) vt[i].clear();
	for(int i = 0, lc; i < vtp.size() - 1; i++){
		lc = lca(vtp[i], vtp[i + 1]);
		vt[lc].push_back(vtp[i + 1]);
	}
	rt = vtp[0];
	return ;
}

void dfs_on_vt(int u, int pre, int D){
	dp[u] = (!vt[u].size()) * 1e18;
	for(int v : vt[u]){
		dfs_on_vt(v, u, D);
		dp[u] += dp[v];
	}
	dp[u] = min(dp[u], query_min(D - dep[u], D - dep[pre] - 1));
	return ;
}

void work(){
	init();

	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i], stc[i][0] = a[i];
	for(int i = 2; i <= n; i++) lg2[i] = lg2[i >> 1] + 1;
	for(int i = 1; i <= 17; i++)
		for(int j = 1; j + (1 << i) - 1 <= n; j++)
			stc[j][i] = min(stc[j][i - 1], stc[j + (1 << (i - 1))][i - 1]);

	for(int i = 1; i < n; i++){
		int x, y;
		cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1, 0);

	int ans = 0;
	for(int i = 1; i <= n; i++) if(h[i].size()){
		build_virtual_tree(h[i]);
		dfs_on_vt(rt, 0, i);
		ans += dp[rt];
	}
	cout << ans << "\n";
	return ;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int T; cin >> T;
	while(T--) work();
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 18148kb

input:

3
4
10 15 40 1
1 2
2 3
2 4
5
10 5 1 100 1000
1 2
2 3
2 4
4 5
4
1000 200 10 8
1 2
2 3
3 4

output:

35
17
1218

result:

ok 3 number(s): "35 17 1218"

Test #2:

score: -100
Memory Limit Exceeded

input:

3000
54
43 44 11 49 17 14 7 30 35 12 34 14 15 8 29 47 30 31 39 17 26 23 26 45 34 50 49 13 35 18 29 15 13 44 47 5 22 20 19 46 30 22 26 13 47 46 43 27 48 48 13 14 30 44
1 2
1 3
2 4
3 5
4 6
2 7
4 8
1 9
3 10
1 11
8 12
2 13
9 14
1 15
1 16
15 17
15 18
7 19
1 20
19 21
13 22
10 23
17 24
9 25
9 26
24 27
8 28...

output:


result: