Submission #1158068

#TimeUsernameProblemLanguageResultExecution timeMemory
1158068SmuggingSpunCat Exercise (JOI23_ho_t4)C++20
100 / 100
151 ms50504 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;
int n, P[lim], A[lim], B[lim];
namespace sub123{
	void solve(){
		vector<vector<int>>p(n + 1, vector<int>(n + 1));
		for(int i = 1; i <= n; i++){
			p[i][i] = i;
			for(int j = i + 1; j <= n; j++){
				p[i][j] = (P[j] > P[p[i][j - 1]] ? j : p[i][j - 1]);
			}
		}
		function<int(int, int)>dp;
		dp = [&] (int l, int r){
			int i = p[l][r];
			return max(l == i ? 0 : dp(l, i - 1) + i - p[l][i - 1], r == i ? 0 : dp(i + 1, r) + p[i + 1][r] - i);
		};
		cout << dp(1, n);
	}
}
namespace sub4567{
	vector<int>g[lim];
	int 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[edge_vertex[i]]){
				maximize(ans, ll(distance(s, edge_vertex[i])) + dfs_2(edge_vertex[i]));
			}
		}
		return ans;
	}
	void solve(){
		for(int i = 1; i < n; 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());
	}
}
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];
	}
	bool is_sub123 = true;
	for(int i = 1; i < n; i++){
		cin >> A[i] >> B[i];
		if(A[i] != i && B[i] != i + 1){
			is_sub123 = false;
		}
	}
	if(n <= 5000 && is_sub123){
		sub4567::solve();
	}
	else{
		sub4567::solve();
	}
}

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:118:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  118 |                 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...