显示代码纯文本
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,q,a[N],w[N],head[N],next[N];
void add(int f,int t){
static int cnt=0;
w[++cnt]=t;
next[cnt]=head[f];
head[f]=cnt;
}
int fa[N],dep[N],Q[N],size;
void dfs(int x){
Q[++size]=x;
for (int i=head[x];i;i=next[i])
if (!fa[w[i]]) fa[w[i]]=x,dep[w[i]]=dep[x]+1,dfs(w[i]);
}
int ance[16][N];
int go(int x,int k){
for (int i=0;i<16;i++)
if (k>>i&1) x=ance[i][x];
return x;
}
int lca(int x,int y){
if (dep[x]<dep[y]) swap(x,y);
x=go(x,dep[x]-dep[y]);
for (int i=15;i>=0;i--)
if (ance[i][x]!=ance[i][y]) x=ance[i][x],y=ance[i][y];
return x!=y?fa[x]:x;
}
int up[N];
const int block_size=200;
struct array{
int v[N];
void init(){
for (int i=1;i<=n;i++) up[i]=fa[up[i]];
for (int i=1;i<=size;i++){
int x=Q[i];
v[x]^=a[x];
if (up[x]) v[x]^=v[up[x]];
}
}
int query(int x,int y){return v[x]^v[y]^a[y];}
}A[block_size+10];
int query(int x,int y,int k){
if (k<=block_size) return A[k].query(x,y);
int ans=a[y];
for (;x!=y;x=go(x,k)) ans^=a[x];
return ans;
}
int main()
{
freopen("xor_xian.in","r",stdin);
freopen("xor_xian.out","w",stdout);
scanf("%d%d",&n,&q);
for (int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
fa[1]=1;dfs(1);fa[1]=0;
for (int i=1;i<=n;i++) scanf("%d",&a[i]),up[i]=i;
for (int i=1;i<=block_size;i++) A[i].init();
for (int i=1;i<=n;i++) ance[0][i]=fa[i];
for (int j=1;j<16;j++)
for (int i=1;i<=n;i++)
ance[j][i]=ance[j-1][ance[j-1][i]];
while (q--){
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
int LCA=lca(x,y),len=dep[x]+dep[y]-2*dep[LCA];
int ans=query(x,go(x,(dep[x]-dep[LCA])/k*k),k);//含LCA
int up=len%k;
if (dep[y]-dep[LCA]>up){
y=go(y,up);
ans^=query(y,go(y,(dep[y]-dep[LCA]-1)/k*k),k);//不含LCA
}
printf("%d\n",ans);
}
return 0;
}