【描述】
給定一棵N個節點的樹,每個點有一個權值,對於M個詢問(u,v,k),你需要回答u xor lastans和v這兩個節點間第K小的點權。其中lastans是上一個詢問的答案,初始爲0,即第一個詢問的u是明文。
【輸入】
第一行兩個整數N,M。
第二行有N個整數,其中第i個整數表示點i的權值。
後面N-1行每行兩個整數(x,y),表示點x到點y有一條邊。
最後M行每行兩個整數(u,v,k),表示一組詢問
【輸出】
M行,表示每個詢問的答案。最後一個詢問不輸出換行符
【思路】
我們先來考慮序列第k大。我們查詢[l,r]的情況,變成查詢r和l-1。那麼樹上也可以類似操作。我們在每個節點維護其到根節點的信息。路徑上的信息可以通過得到。所以我們只需要同時在四個點對應的樹上查詢即可。
代碼:
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define re register
using namespace std;
const int N=1e5+5;
int n,m,a,b,k,c[N],val[N],tot,rt[N],las;
tr1::unordered_map<int,int>f;
inline int red()
{
int data=0;int w=1; char ch=0;
ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
return data*w;
}
namespace tree{
int ch[N*30|1][2],siz[N*30|1],cnt=0;
int change(int v,int l,int r,int pos)
{
int u=++cnt;siz[u]=siz[v]+1;
if(l==r)return cnt;
int mid=(l+r)>>1;
ch[u][0]=ch[v][0];ch[u][1]=ch[v][1];
if(pos<=mid)ch[u][0]=change(ch[v][0],l,mid,pos);
else ch[u][1]=change(ch[v][1],mid+1,r,pos);
return u;
}
int query(int a,int b,int c,int d,int l,int r,int k)
{
if(l==r)return l;
int ls=siz[ch[a][0]]+siz[ch[b][0]]-siz[ch[c][0]]-siz[ch[d][0]];
int mid=(l+r)>>1;
if(ls>=k)return query(ch[a][0],ch[b][0],ch[c][0],ch[d][0],l,mid,k);
else return query(ch[a][1],ch[b][1],ch[c][1],ch[d][1],mid+1,r,k-ls);
}
}
using tree::change;
using tree::query;
namespace LCA{
vector<int>g[N];
int dep[N]={0,1},fa[N][18];
void dfs(int u){
rt[u]=change(rt[fa[u][0]],1,tot,f[val[u]]);
for(int re i=1;(1<<i)<=(dep[u]);i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int re i=g[u].size()-1;~i;--i){int v=g[u][i];if(!dep[v])dep[v]=dep[u]+1,fa[v][0]=u,dfs(v);}
}
inline int lca(int a,int b)
{
if(dep[a]<dep[b])swap(a,b);
int t=dep[a]-dep[b];
for(int re i=0;(1<<i)<=t;++i)
if(t&(1<<i))a=fa[a][i];
if(a==b)return a;
for(int re i=17;~i;--i)
if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
return fa[a][0];
}
}
using LCA::g;
using LCA::dfs;
using LCA::lca;
int main()
{
n=red();m=red();
for(int re i=1;i<=n;i++)c[i]=val[i]=red();
sort(c+1,c+(tot=n)+1);tot=unique(c+1,c+n+1)-c-1;
for(int re i=1;i<=tot;i++)f[c[i]]=i;
for(int re i=1;i^n;i++)a=red(),b=red(),g[a].push_back(b),g[b].push_back(a);dfs(1);
while(m--){
a=red()^las;b=red();k=red();int lc1=lca(a,b),lc2=LCA::fa[lc1][0];
printf("%d",las=c[query(rt[a],rt[b],rt[lc1],rt[lc2],1,tot,k)]);if(m)putchar('\n');
}
}