Submission #878472

#TimeUsernameProblemLanguageResultExecution timeMemory
878472phoenix0423Cat Exercise (JOI23_ho_t4)C++17
100 / 100
222 ms51960 KiB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pll;
#define fastio ios::sync_with_stdio(false), cin.tie(0)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define f first
#define s second
const int INF = 1e9;
const int maxn = 2e5 + 5;
vector<int> adj[maxn];
int h[maxn], id[maxn], n;
vector<pll> edge;
int dep[maxn], par[maxn], succ[maxn][18];
struct DSU{
	vector<int> par, siz;
	int n;
	DSU(int _n) : n(_n){
		par.resize(n);
		for(int i = 0; i < n; i++) par[i] = i;
	}
	int root(int x){ return x == par[x] ? x : par[x] = root(par[x]);}
	void unite(int x, int y){
		y = root(y); // h[x] > h[y]
		par[y] = x;
	}
};

void dfs(int pos, int prev){
	for(int i = 1; i < 18; i++) succ[pos][i] = succ[succ[pos][i - 1]][i - 1];
	for(auto x : adj[pos]){
		if(x == prev) continue;
		dep[x] = dep[pos] + 1;
		succ[x][0] = pos;
		dfs(x, pos);
	}
}
void lift(int &b, int steps){
	for(int i = 17; i >= 0; i--){
		if(steps & (1 << i)) b = succ[b][i];
	}
}
int sld(int a, int b){
	int ret = 0;
	for(int i = 17; i >= 0; i--){
		if(succ[a][i] != succ[b][i]){
			a = succ[a][i];
			b = succ[b][i];
			ret += (1 << i) * 2;
		}
	}
	return ret + 2;
}
int dist(int a, int b){
	int ret = 0;
	if(dep[a] > dep[b]) swap(a, b);
	ret += dep[b] - dep[a], lift(b, dep[b] - dep[a]);
	if(a == b) return ret;
	return ret + sld(a, b);
}
int main(void){
	fastio;
	cin>>n;
	for(int i = 0; i < n; i++) cin>>h[i], h[i]--, id[h[i]] = i;
	for(int i = 0; i < n - 1; i++){
		int a, b;
		cin>>a>>b;
		a--, b--;
		adj[a].pb(b);
		adj[b].pb(a);
		if(h[a] < h[b]) swap(a, b);
		edge.eb(a, b);
	}
	sort(ALL(edge), [&](pll a, pll b) -> bool { return h[a.f] < h[b.f];});
	dfs(0, 0);
	DSU dsu(n);
	vector<ll> ans(n); // store ans of element of height i
	for(auto [a, b] : edge){ // h[a] > h[b]
		b = dsu.root(b);
		ans[h[a]] = max(ans[h[a]], ans[h[b]] + dist(a, b));
		dsu.unite(a, b);
	}
	cout<<ans[n - 1]<<"\n";
}
#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...