Submission #1261524

#TimeUsernameProblemLanguageResultExecution timeMemory
1261524vlomaczkCat Exercise (JOI23_ho_t4)C++20
0 / 100
34 ms53712 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

ll M = 200'010;
ll maxlog = 17;
vector<vector<pair<ll, ll>>> g(M);
vector<ll> p(M), h(M), depth(M);
vector<vector<ll>> jump(M, vector<ll>(maxlog+1));
vector<ll> rep(M, 0), sajz(M, 1), maks(M, 0), par(M, 0), dp(M, 0);
vector<vector<pair<ll, ll>>> rep_changes, sajz_changes, maks_changes;
vector<bool> turned_on(M, 0);

void mw_dfs(ll v, ll p, ll a) {
	rep_changes.back().push_back({v, rep[v]});
	rep[v] = a;
	for(auto[u, k] : g[v]) if(u!=p && turned_on[k]) mw_dfs(u, v, a);
}

void Union(ll a, ll b) {
	a = rep[a];
	b = rep[b];
	if(a==b) return;
	if(sajz[b] > sajz[a]) swap(a, b);
	rep_changes.push_back({});
	sajz_changes.push_back({{a, sajz[a]}, {b, sajz[b]}});
	maks_changes.push_back({{a, maks[a]}, {b, maks[b]}});
	mw_dfs(b, 0, a);
	sajz[a] += sajz[b];
	maks[a] = max(maks[a], maks[b]);
}

void rollback() {
	for(auto[a, b] : rep_changes.back()) rep[a] = b;
	for(auto[a, b] : sajz_changes.back()) sajz[a] = b;
	for(auto[a, b] : maks_changes.back()) maks[a] = b;
	rep_changes.pop_back();
	sajz_changes.pop_back();
	maks_changes.pop_back();
}

void jump_dfs(ll v, ll p) {
	depth[v] = depth[p] + 1;
	jump[v][0] = p;
	for(ll i=1; i<=maxlog; ++i) jump[v][i] = jump[jump[v][i-1]][i-1];
	for(auto[u, k] : g[v]) if(u!=p) jump_dfs(u, v);
}

ll lca(ll a, ll b) {
	if(depth[b] > depth[a]) swap(a, b);
	for(ll i=maxlog; i>=0; --i) {
		if(depth[jump[a][i]] >= depth[b]) a = jump[a][i];
	}
	if(a==b) return a;
	for(ll i=maxlog; i>=0; --i) {
		if(jump[a][i]!=jump[b][i]) {
			a = jump[a][i];
			b = jump[b][i];
		}
	}
	return jump[a][0];
}

ll dist(ll a, ll b) {
	return depth[a] + depth[b] - 2*depth[lca(a, b)];
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	ll n;
	cin >> n;
	for(ll i=1; i<=n; ++i) {
		cin >> h[i];
		p[h[i]] = i;
	}
	for(ll i=1; i<n; ++i) {
		ll a, b;
		cin >> a >> b;
		g[a].push_back({b, i});
		g[b].push_back({a, i});
	}
	for(ll i=1; i<=n; ++i) rep[i] = i;
	for(ll i=1; i<=n; ++i) maks[i] = h[i];
	for(ll i=1; i<=n; ++i) {
		ll v = p[i];
		for(auto[u, k] : g[v]) {
			if(h[u] > h[v] || turned_on[k]) continue;
			Union(v, u);
			turned_on[k] = 1;
		}
	}
	jump_dfs(1, 0);
	priority_queue<ll, vector<ll>, greater<ll>> pq;
	pq.push(n);
	vector<int> stos;
	while(pq.size()) {
		ll v = p[pq.top()]; pq.pop();
		for(auto[u, k] : g[v]) {
			if(turned_on[k]) rollback();
		}
		for(auto[u, k] : g[v]) {
			if(turned_on[k]) {
				turned_on[k] = 0;
				pq.push(maks[rep[u]]);
				par[p[maks[rep[u]]]] = v;
			}
		}
		stos.push_back(v);
	}
	reverse(stos.begin(), stos.end());
	for(auto v : stos) {
		int p = par[v];
		dp[p] = max(dp[p], dist(p, v)+dp[v]);
	}
	cout << dp[p[n]] << "\n";

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