제출 #1324466

#제출 시각아이디문제언어결과실행 시간메모리
1324466ppmn_6Cat Exercise (JOI23_ho_t4)C++20
100 / 100
423 ms80084 KiB
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
 
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
 
// https://codeforces.com/blog/entry/79148
class Timer: chrono::high_resolution_clock {
    const time_point start_time;
public:
    Timer(): start_time(now()) {}
    rep elapsed_time() const {
		return chrono::duration_cast<chrono::milliseconds>(now() - start_time).count();
	}
} timer;

struct DSU {
	int n;
	vector<int> p, sz, ma;
	DSU(vector<int> a) {
		n = a.size() - 1;
		ma = a;
		p.resize(n + 1);
		iota(p.begin(), p.end(), 0);
		sz.resize(n + 1, 1);
	}
	int root(int a) {
		if (p[a] != a) {
			p[a] = root(p[a]);
		}
		return p[a];
	}
	void join(int a, int b) {
		a = root(a);
		b = root(b);
		if (sz[a] > sz[b]) {
			swap(a, b);
		}
		p[a] = b;
		sz[b] += sz[a];
		ma[b] = max(ma[b], ma[a]);
	}
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n, cur = 0;
	cin >> n;
	vector<int> a(n + 1), l(n + 1), rev(n + 1);
	vector<ll> dist(n + 1, 0), dp(n + 1, 0);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		rev[a[i]] = i;
	}
	vector<vector<int>> tree(n + 1), up(n + 1);
	for (int i = 1; i < n; i++) {
		int u, v;
		cin >> u >> v;
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	auto dfs = [&] (auto self, int c, int p)->void {
		if (p) {
			int u = p, pos = 0;
			while (true) {
				up[c].push_back(u);
				if (pos >= up[u].size()) {
					break;
				}
				u = up[u][pos];
				pos++;
			}
		}
		l[c] = cur;
		for (auto &v : tree[c]) {
			if (v != p) {
				cur++;
				dist[v] = dist[c] + 1;
				self(self, v, c);
			}
		}
	};
	auto lca = [&] (int u, int v) {
		if (u == v) {
			return u;
		}
		if (l[u] > l[v]) {
			swap(u, v);
		}
		int c = v;
		while (l[c] > l[u]) {
			if (l[up[c][0]] <= l[u]) {
				c = up[c][0];
			}
			else {
				for (int i = up[c].size() - 1; i >= 0; i--) {
					if (l[up[c][i]] > l[u]) {
						c = up[c][i];
						break;
					}
				}
			}
		}
		return c;
	};
	dfs(dfs, 1, 0);
	DSU dsu(a);
	for (int i = 1; i <= n; i++) {
		int u = rev[i];
		for (auto &v : tree[u]) {
			if (a[v] < i) {
				int x = dsu.ma[dsu.root(v)];
				dp[u] = max(dp[u], dp[rev[x]] + dist[u] + dist[rev[x]] - 2 * dist[lca(u, rev[x])]);
				dsu.join(u, v);
			}
		}
	}
	cout << dp[rev[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...