map + 啓發式合併

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>

using namespace std;

typedef long long LL;

#define REP(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define DREP(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
#define EREP(i, a) for(register int i = (be[a]); i != -1; i = nxt[i])
#define mem(a, b) memset((a), b, sizeof(a))

template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

char buff[1 << 25], *buf = buff;

template <class T>
T read(T sum = 0, T fg = 0)
{
	while(*buf < '0' || *buf > '9') { fg |= *buf == '-'; buf++; }
	while(*buf >= '0' && *buf <= '9') { sum = sum * 10 + *buf - '0'; buf++; }
	return fg ? -sum : sum;
}

const int Size = 400010;

int to[Size << 1], nxt[Size << 1], be[Size], e;

void add(int x, int y) { to[e] = y; nxt[e] = be[x]; be[x] = e; e++; }

void init() { mem(be, -1); e = 0; }

int n;
int val[Size];
int ans[Size];

map <int, int> mp[Size], now[Size];
map <int, int>::iterator it;

void dfs(int x, int f)
{
	mp[x][val[x]] = 1;
	now[x][1] = val[x];
	EREP(i, x)
	{
		int y = to[i];
		if(y == f) continue;
		dfs(y, x);
		if(mp[x].size() < mp[y].size())
		{
			swap(mp[x], mp[y]);
			swap(now[x], now[y]);
		}
		for(it = mp[y].begin(); it != mp[y].end(); it++)
		{
			now[x][mp[x][it -> first]] -= it -> first;
			mp[x][it -> first] += mp[y][it -> first];
			now[x][mp[x][it -> first]] += it -> first;
		}
		mp[y].clear();
		now[y].clear();
	}
	it = now[x].end(); it--;
	ans[x] = it -> second;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("star.in", "r", stdin);
	freopen("star.out", "w", stdout);
#endif
	fread(buff, 1, 1 << 25, stdin);
	init();
	n = read<int>();
	REP(i, 1, n) val[i] = read<int>();
	REP(i, 1, n - 1)
	{
		int x = read<int>(), y = read<int>();
		add(x, y); add(y, x);
	}
	dfs(1, -1);
	REP(i, 1, n) printf("%d ", ans[i]); puts("");
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章