一:【题意】
二:【解法】
- 主席树
- 对于每个节点u,建立u->root路径上的权值线段树tree[u]
- 对于每次询问u,v
- 树上差分得到tr=tree[u]+tree[v]-tree[lca(u,v)-tree[fa[lca(u,v)]]
- 在tr上做线段树二分
三:【代码】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,Q=4*N+N*log2(N);
int nw[N];
vector<int> lsh;
vector<int> mp[N];
int tr[N];
struct node{
int l,r;
int son[2];
int sum;
#define l(q) tree[q].l
#define r(q) tree[q].r
#define sum(q) tree[q].sum
#define ls(q) tree[q].son[0]
#define rs(q) tree[q].son[1]
}tree[Q];int cnt;
void push_up(int q){
sum(q)=sum(ls(q))+sum(rs(q));
}
void build(int &q,int l,int r){
if(q==0) q=++cnt;
l(q)=l;r(q)=r;
if(l==r) return ;
int mid=l+r>>1;
build(ls(q),l,mid);
build(rs(q),mid+1,r);
push_up(q);
}
void update(int las,int &now,int tp,int d){
if(now==0) now=++cnt;
tree[now]=tree[las];
int l=l(las),r=r(las);
if(l==r){
sum(now)=sum(las)+d;/////
return ;
}
int mid=l+r>>1;
int s=(tp>mid);
update(tree[las].son[s],tree[now].son[s]=0,tp,d);
push_up(now);
}
void Build(int u,int fa){
update(tr[fa],tr[u],nw[u],1);
for(auto v:mp[u]){
if(v==fa) continue;
Build(v,u);
}
}
int query(int u,int v,int lca,int flca,int K){
int l=l(u),r=r(u);
if(l==r) return l;
int res=sum(ls(u))+sum(ls(v))-sum(ls(lca))-sum(ls(flca));
if(K<=res) return query(ls(u),ls(v),ls(lca),ls(flca),K);
else return query(rs(u),rs(v),rs(lca),rs(flca),K-res);
}
int son[N],siz[N],dep[N];
int fa[N];
void Son(int u,int pa){
fa[u]=pa;
siz[u]=1;
dep[u]=dep[pa]+1;
for(auto v:mp[u]){
if(v==pa) continue;
Son(v,u);
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
int top[N];
void Line(int u,int tp){
top[u]=tp;
if(!son[u]) return ;
Line(son[u],tp);
for(auto v:mp[u]){
if(v==fa[u]||v==son[u]) continue;
Line(v,v);
}
}
int LCA(int a,int b){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]]) swap(a,b);
a=fa[top[a]];
}
if(dep[a]>dep[b]) swap(a,b);
return a;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,m;cin>>n>>m;
lsh.push_back(-1);
for(int i=1;i<=n;i++){
cin>>nw[i];
lsh.push_back(nw[i]);
}
sort(lsh.begin(),lsh.end());
lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end());
for(int i=1;i<=n;i++) nw[i]=lower_bound(lsh.begin(),lsh.end(),nw[i])-lsh.begin();
for(int i=1;i<n;i++){
int a,b;cin>>a>>b;
mp[a].push_back(b);
mp[b].push_back(a);
}
build(tr[0],1,n);
Build(1,0);
Son(1,0);
Line(1,1);
int ans=0;
while(m--){
int u,v,K;cin>>u>>v>>K;
u^=ans;
int lca=LCA(u,v);
ans=lsh[query(tr[u],tr[v],tr[lca],tr[fa[lca]],K)];
cerr<<"-->";
cout<<ans<<"\n";
}
return 0;
}