Submission #1158069

#TimeUsernameProblemLanguageResultExecution timeMemory
1158069SmuggingSpunCat Exercise (JOI23_ho_t4)C++20
100 / 100
174 ms47404 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
template<class T>void maximize(T& a, T b){
	if(a < b){
		a = b;
	}
}
const int lim = 2e5 + 5;
vector<int>g[lim];
int n, P[lim], A[lim], B[lim], edge_vertex[lim], h[lim], up[lim][18];
void dfs_1(int s){
	for(int& i : g[s]){
		int d = A[i] ^ B[i] ^ s;
		if(d != up[s][0]){
			h[d] = h[up[d][0] = s] + 1;
			for(int i = 1; i < 18; i++){
				up[d][i] = up[up[d][i - 1]][i - 1];
			}
			dfs_1(d);
		}
	}
}
int lca(int u, int v){
	if(h[u] < h[v]){
		swap(u, v);
	}
	for(int k = h[u] - h[v], i = 0; i < 18; i++){
		if(1 << i & k){
			u = up[u][i];
		}
	}
	if(u == v){
		return u;
	}
	for(int i = 17; i > -1; i--){
		if(up[u][i] != up[v][i]){
			u = up[u][i];
			v = up[v][i];
		}
	}
	return up[u][0];
}
int distance(int u, int v){
	return h[u] + h[v] - (h[lca(u, v)] << 1);
}
ll dfs_2(int s){
	ll ans = 0;
	for(int& i : g[s]){
		int d = A[i] ^ B[i] ^ s;
		if(P[s] > P[d]){
			maximize(ans, ll(distance(s, edge_vertex[i])) + dfs_2(edge_vertex[i]));
		}
	}
	return ans;
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
	cin >> n;
	for(int i = 1; i <= n; i++){
		cin >> P[i];
	}
	for(int i = 1; i < n; i++){
		cin >> A[i] >> B[i];
		g[A[i]].emplace_back(i);
		g[B[i]].emplace_back(i);
	}
	vector<int>vertex(n), lab(n + 1), max_lab(n + 1);
	iota(vertex.begin(), vertex.end(), 1);
	sort(vertex.begin(), vertex.end(), [&] (int i, int j){
		return P[i] < P[j];
	});
	iota(lab.begin(), lab.end(), 0);
	iota(max_lab.begin(), max_lab.end(), 0);
	auto find_set = [&] (int N){
		while(N != lab[N]){
			N = lab[N] = lab[lab[N]];
		}
		return N;
	};
	auto merge = [&] (int u, int v){
		lab[u = find_set(u)] = v =  find_set(v);
		if(P[max_lab[v]] < P[max_lab[u]]){
			max_lab[v] = max_lab[u];
		}
	};
	for(int& u : vertex){
		for(int& i : g[u]){
			int v = A[i] ^ B[i] ^ u;
			if(P[u] > P[v]){
				edge_vertex[i] = max_lab[v = find_set(v)];
				merge(u, v);
			}
		}
	}
	memset(up, h[1] = 0, sizeof(up));
	dfs_1(1);
	cout << dfs_2(vertex.back());
}

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:61:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   61 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...