本题可以考虑dfs序将树映射到顺序表上,这么做方便线段树操作一个节点和他的所有子孙节点,注意是所有子孙节点。 这时考虑一个问题,如果一下子把所有元素都映射上去,并不能依赖线段树解决涉及深度浅节点的询问。 可以将深度深的节点对应的顺序表元素先置0,等需要它了再放进去,这就需要dfs预处理顺序表(即线段树专用表)和节点的映射关系,同时也要处理每个节点的子孙节点的个数,这两步操作类似传统树链剖分题的与处理环节。 从涉及深度浅的查询开始下手,假设查询是节点x开始往后y步,遂que(1,n,1,pos[x],pos[x]+num[x]-1)查询节点x的所有子孙节点中的最大值,注意这时深度大于y的x的子孙节点尚未置入,即0,对答案不构成影响。可以考虑给查询排序。 如果不给查询排序,主席树应该也可以做,只不过这个做法已经很头大了。 另外好像不涉及区间改动的线段树无需build()建树? 本人赛后补题。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long;
#define nm(a,b) ll a,b;cin>>a>>b;
#define rep(i,a,b) for(ll i=a;i<=b;++i)
#define g(n) ll n;cin>>n;
#define N 500001
ll to[2 * N], nxt[2 * N], node[N], dep[N], num[N], pos[N], vis[N];ll cnt = 0;ll ma = -1;ll top = 0;
ll val[500001 << 4]; ll v[N];
inline void add(ll a, ll b) {
	to[cnt] = b;
	nxt[cnt] = node[a];
	node[a] = cnt++;
}
ll pre_dfs(ll x) {
	ma = max(ma, dep[x]);
	num[x] = 1;
	pos[x] = ++top;
	for (int i = node[x]; i; i = nxt[i]) {
		int j = to[i];
		if (!vis[j]) {
			vis[j] = 1;
			dep[j] = dep[x] + 1;
			num[x] += pre_dfs(j);
		}
	}
	return num[x];
}
void update(ll l, ll r, ll x, ll pos, ll v) {
	if (l == r) {
		val[x] = max(val[x], v); return;
	}
	ll mid = l + r >> 1;
	if (pos <= mid)update(1, mid, x << 1, pos, v);
	else update(mid + 1, r, x << 1 | 1, pos, v);
	val[x] = max(val[x << 1], val[x << 1 | 1]);
}
ll que(ll l, ll r, ll x, ll cl, ll cr) {
	if (cl <= l && r <= cr) {
		return val[x];
	}
	ll ret = -1;
	ll mid = l + r >> 1;
	if (cl <= mid)ret = que(1, mid, x << 1, cl, cr);
	if (cr > mid)ret = max(ret, que(mid + 1, r, x << 1 | 1, cl, cr));
	return ret;
}
ll ans[N];
int main() {
	g(n);
	rep(i, 1, n) {
		cin >> v[i];
	}
	rep(i, 1, n - 1) {
		nm(x, y);
		add(x, y);
		add(y, x);
	}
	vis[1] = 1;
	dep[1] = 1;
	ll ppp = -1;
	pre_dfs(1);
	vector<vector<pair<ll, ll> > >query(ma + 1);
	g(xxx);
	rep(i,1,xxx) {
		nm(a, b);
		query[dep[b] + a].push_back({ b,i });
	}
	mst(vis, 0);
	queue<ll> q;
	q.push(1);
	vis[1] = 1;
	while (!q.empty()) {
		auto p = q.front();
		q.pop();
		if (query[dep[p] - 1].size()) {
			for (auto& it : query[dep[p] - 1]) {
				ans[it.f2] = que(1, n, 1, pos[it.f1], pos[it.f1] + num[it.f1] - 1);
			}
			query[dep[p] - 1].clear();
		}
		update(1, n, 1, pos[p], v[p]);
		for (int i = node[p]; i; i = nxt[i]) {
			int j = to[i];
			if (!vis[j]) {
				vis[j] = 1;
				q.push(j);
			}
		}
	}
	if (query[ma].size()) {
		for (auto& it : query[ma]) {
			ans[it.f2] = que(1, n, 1, pos[it.f1], pos[it.f1] + num[it.f1] - 1);
		}
	}
	rep(i, 1, xxx) {
		cout << ans[i] << endl;
	}
}