分块求调
查看原帖
分块求调
755850
Sword_wielder楼主2024/2/26 12:55
#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
int cnt[M][N], bl[N];
int l[M], r[M], mx[M][M], SUM[M][M];
int a[N], b[N], sum, tot[N];
vector <int> G[N];
int dep[N], son[N], mxs[N], dfn[N], cr[N], le[N], ri[N], NOW, top[N];
void dfs1 (int u, int lst) {	
	top[u] = u;
	son[u] = 1;
	for (int i = 0 ; i < G[u].size() ; i ++) {
		int v = G[u][i];
		if (v != lst) {
			dfs1 (v, u);
			son[u] += son[v];
			if (son[mxs[u]] < son[v]) mxs[u] = v;
		}
	}
}
void dfs2 (int u, int lst) {
	dfn[u] = ++ NOW;
	cr[NOW] = u;
	ri[u] = le[u] = NOW;
	if (mxs[u]) {
		top[mxs[u]] = top[u];
		dfs2 (mxs[u], u);
		le[u] = min(le[u], le[mxs[u]]);
		ri[u] = max(ri[u], ri[mxs[u]]);
	}
	for (int i = 0 ; i < G[u].size() ; i ++) {
		int v = G[u][i];
		if (v != lst && v != mxs[u]) {
			dfs2 (v, u);
			le[u] = min(le[u], le[v]);
			ri[u] = max(ri[u], ri[v]);
		}
	}
}
int query(int pl, int pr) {
//	memset(tot, 0, sizeof(tot));
	if (bl[pl] + 1 >= bl[pr]) {
		int ans = 0, ans2 = 0;
		for (int i = pl ; i <= pr ; i ++) {
			tot[a[i]] ++;
			if (tot[a[i]] > tot[ans]) ans2 = ans = a[i];
			else if (tot[a[i]] == tot[ans]) ans2 += a[i];
		}
		for (int i = pl ; i <= pr ; i ++) tot[a[i]] --;
		return ans2;
	} else {
		int ans = mx[bl[pl] + 1][bl[pr] - 1], ans2 = SUM[bl[pl] + 1][bl[pr] - 1];
		for (int i = pl ; i <= r[bl[pl]] ; i ++) {
			tot[a[i]] ++;
			int xx = tot[a[i]] + cnt[bl[pr] - 1][a[i]] - cnt[bl[pl]][a[i]];
			int yy = tot[ans] + cnt[bl[pr] - 1][ans] - cnt[bl[pl]][ans];
			if (xx > yy) ans2 = ans = a[i];
			else if (xx == yy) ans2 += a[i];
 		}
		for (int i = l[bl[pr]] ; i <= pr ; i ++) {
			tot[a[i]] ++;
			int xx = tot[a[i]] + cnt[bl[pr] - 1][a[i]] - cnt[bl[pl]][a[i]];
			int yy = tot[ans] + cnt[bl[pr] - 1][ans] - cnt[bl[pl]][ans];
			if (xx > yy) ans2 = ans = a[i];
			else if (xx == yy) ans2 += a[i];
		}
		for (int i = pl ; i <= r[bl[pl]] ; i ++) tot[a[i]] --;
		for (int i = l[bl[pr]] ; i <= pr ; i ++) tot[a[i]] --;
		return ans2;
	}
}
signed main() {
// 	freopen("P4168.in", "r", stdin);
// 	freopen("P4168.out", "w", stdout);
	int n;
	cin >> n;
	const int B = sqrt(n);
	for (int i = 1 ; i <= n ; i ++) cin >> a[i], b[i] = a[i]; 
	int m = n - 1;
	while (m --) {
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs1(1, 1), dfs2(1, 1);
	for (int i = 1 ; i <= n ; i ++)
		a[dfn[i]] = b[i];
	for (int i = 1 ; i <= n ; i ++) 
		bl[i] = i / B + (bool)(i % B);
	for (int i = 1 ; i <= bl[n] ; i ++)
		l[i] = r[i - 1] + 1, r[i] = l[i] + B - 1;
	sum = bl[n];
	r[bl[n]] = n;
	for (int i = 1 ; i <= n ; i ++) 
		cnt[bl[i]][a[i]] ++;
	for (int i = 1 ; i <= sum ; i ++)
		for (int j = 1 ; j <= n ; j ++)
			cnt[i][j] += cnt[i - 1][j];
	for (int i = 1 ; i <= sum ; i ++) {
		for (int j = i ; j <= sum ; j ++) {
			mx[i][j] = mx[i][j - 1];
			SUM[i][j] = SUM[i][j - 1];
			for (int k = l[j] ; k <= r[j] ; k ++) {			
				int xx = cnt[j][a[k]] - cnt[i - 1][a[k]];
				int yy = cnt[j][mx[i][j]] - cnt[i - 1][mx[i][j]];
				if (xx > yy) SUM[i][j] = mx[i][j] = a[k]; 
				else if (xx == yy) SUM[i][j] += a[k];
			}
		}
	}
	for (int i = 1 ; i <= n ; i ++)
		cout << query(le[i], ri[i]) << ' ';
	return 0;
}
2024/2/26 12:55
加载中...