Cod sursa(job #2237751)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 2 septembrie 2018 22:42:30
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.98 kb
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;

ifstream fi("guvern.in");
ofstream fo("guvern.out");

using pii = pair<int, int>;

const int N = 2e5 + 5;


vector<int> g[N], forest[N];
int aib[N], val[N], lvl[N], line[N], dep[N], dp[N], st[N], dr[N];

set<pii> above;
set<int> s;
int n, ant, ptr;


static inline int lsb(const int &arg) {
	return arg & -arg; }

static int query(int pos) {
	int ant = 0;
	for (; pos > 0; pos-= lsb(pos))
		ant+= aib[pos];
	return ant; }

static int query(int a, int b) {
	return query(b) - query(a - 1); }

static void update(int pos, int val) {
	for (; pos < N; pos+= lsb(pos))
		aib[pos]+= val; }


static void init(int u, int far = 0) {
	auto it = above.lower_bound(pii(val[u], u));
	if (it != above.end()) {
		forest[it->second].push_back(u);
		dep[u] = it->second; }

	st[u] = ++ptr;
	line[ptr] = u;

	above.emplace(val[u], u);
	for (auto v: g[u]) if (v != far) {
		lvl[v] = lvl[u] + 1;
		init(v, u); }
	above.erase(pii(val[u], u));
	dr[u] = ptr; }

static void dfs(int u) {
	for (auto v: forest[u])
		dfs(v);

	sort(begin(forest[u]), end(forest[u]), [&](int a, int b) { return lvl[a] > lvl[b]; });
	for (auto v: forest[u]) {
		update(st[v], dp[v]);
		s.insert(st[v]); }

	for (auto v: forest[u]) {
		int sum = query(st[v], dr[v]) - dp[v];
		if (sum > dp[v]) {
			s.erase(st[v]);
			update(st[v], -dp[v]); }
		else {
			set<int>::iterator tmp, it = s.upper_bound(st[v]);
			while (it != s.end() && *it <= dr[v]) {
				tmp = next(it);
				update(*it, -dp[line[*it]]);
				s.erase(it);
				it = tmp; } } }
	dp[u] = 1;
	for (auto i: s)
		dp[u]+= dp[line[i]];

	ant = max(ant, u == 0 ? dp[u] - 1 : dp[u]);

	for (auto i: s)
		update(i, -dp[line[i]]);
	s.clear(); }


int main() {
	fi >> n;
	for (int a, b, i = 1; i < n; ++i) {
		fi >> a >> b;
		g[a].push_back(b);
		g[b].push_back(a); }
	for (int i = 1; i <= n; ++i)
		fi >> val[i];

	init(1);
	for (int i = 1; i <= n; ++i) if (!dep[i])
		forest[0].push_back(i);

	dfs(0);

	fo << ant << endl;

	return 0; }