- #include <bits/stdc++.h>
- using namespace std;
-
- #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- #define endl "\n"
- #define int long long
-
- const int N = 1e5 + 5;
- const int LG = log2(N) + 1;
-
- int n, q, ct = 0, num = 1e5;
- int a[N], root[N], level[N];
- int st[21*N], st2[21*N], lc[21*N], rc[21*N];
- int tim=0;
- int parent[LG][N];
- vector<int> g[N];
-
- void dfs0(int k, int par, int lvl)
- {
- parent[0][k] = par;
- level[k] = lvl;
- for(auto it:g[k])
- {
- if(it==par)
- continue;
- dfs0(it, k, lvl+1);
- }
- }
-
- void precompute()
- {
- for(int i=1;i<LG;i++)
- for(int j=1;j<=n;j++)
- if(parent[i-1][j])
- parent[i][j]=parent[i-1][parent[i-1][j]];
- }
-
- int LCA(int u, int v)
- {
- if(level[u]<level[v])
- swap(u,v);
- int diff=level[u]-level[v];
- for(int i=LG-1;i>=0;i--)
- {
- if((1<<i) & diff)
- {
- u=parent[i][u];
- }
- }
- if(u==v)
- return u;
- for(int i=LG-1;i>=0;i--)
- {
- if(parent[i][u] && parent[i][u]!=parent[i][v])
- {
- u=parent[i][u];
- v=parent[i][v];
- }
- }
- return parent[0][u];
- }
-
-
- int build(int L, int R)
- {
- int node = ++ct;
- if(L==R)
- return node;
- int M = (L+R)/2;
- lc[node] = build(L, M);
- rc[node] = build(M+1, R);
- return node;
- }
-
- int update(int onode, int L, int R, int pos)
- {
- int node = ++ct;
- if(L==R)
- {
- st[node] = st[onode] + 1;
- st2[node] = st2[onode] + L;
- return node;
- }
- int M = (L+R)/2;
- lc[node] = lc[onode];
- rc[node] = rc[onode];
- if(pos <= M)
- lc[node] = update(lc[onode], L, M, pos);
- else
- rc[node] = update(rc[onode], M+1, R, pos);
- st[node] = st[lc[node]] + st[rc[node]];
- st2[node] = st2[lc[node]] + st2[rc[node]];
- return node;
- }
-
- int query(int nodeu, int nodev, int nodelca, int nodelcapar, int L, int R, int pos)
- {
- if(L==R)
- {
- int have = st[nodeu] + st[nodev] - st[nodelca] - st[nodelcapar];
- int canDefeat = pos/L;
- return min(have, canDefeat);
- }
- int M = (L+R)/2;
- int leftval = st2[lc[nodeu]] + st2[lc[nodev]] - st2[lc[nodelca]] - st2[lc[nodelcapar]];
- int rightval = st2[rc[nodeu]] + st2[rc[nodev]] - st2[rc[nodelca]] - st2[rc[nodelcapar]];
- int defeated = st[lc[nodeu]] + st[lc[nodev]] - st[lc[nodelca]] - st[lc[nodelcapar]];
- if(leftval > pos)
- return query(lc[nodeu], lc[nodev], lc[nodelca], lc[nodelcapar], L, M, pos);
- else
- return defeated + query(rc[nodeu], rc[nodev], rc[nodelca], rc[nodelcapar], M+1, R, pos - leftval);
- }
-
- void dfs(int u, int par)
- {
- int onode = root[par];
- root[u] = update(onode, 1, num, a[u]);
- for(auto &it:g[u])
- {
- if(it==par)
- continue;
- dfs(it, u);
- }
- }
-
- int32_t main()
- {
- IOS;
- cin>>n;
- for(int i=1;i<=n;i++)
- cin>>a[i];
- for(int i=1;i<=n-1;i++)
- {
- int u, v;
- cin>>u>>v;
- g[u].push_back(v);
- g[v].push_back(u);
- }
- cin>>q;
- root[0] = build(1, num);
- dfs0(1, 0, 1);
- precompute();
- dfs(1, 0);
- while(q--)
- {
- int u, v, k;
- cin>>u>>v>>k;
- int lca = LCA(u, v);
- int parlca = parent[0][lca];
- int ans = query(root[u], root[v], root[lca], root[parlca], 1, num, k);
- cout<<ans<<endl;
- }
- return 0;
- }