先用dfs维护每个点到以1为根节点的异或和的d[n],接着,用lca找到最近公共祖先,由异或的性质
a^b^b^c=a^c可以知道,d[a]^d[b] ^公共祖先就相当于最短距离
#include<bits/stdc++.h>
using namespace std;
const int N = 200010, M = 2 * N;
int h[N],e[M],ne[M],idx;
int f[N][20],d[N],dist[N],edge[2 * N];
int aq[N];
int T,n,m,logg;
int c[N];
//d储存深度
queue<int>q;
void add (int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void bfs(){//初始化
q.push(1);
d[1]=1;
while(q.size()){
int x=q.front();
q.pop();
for(int i=h[x];i!=-1;i=ne[i]){
int y=e[i];
if(d[y]) continue;
d[y]=d[x]+1;
dist[y]=dist[x]+edge[i];
f[y][0]=x;
for(int j=1;j<=logg;j++) f[y][j]=f[f[y][j-1]][j-1];
q.push(y);
}
}
}
int lca(int x,int y){//回答一个询问
if(d[x]>d[y]) swap(x,y);
for(int i=logg;i>=0;i--)
if(d[f[y][i]]>=d[x]) y=f[y][i];
if(x==y) return x;
for(int i=logg;i>=0;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
void dfs(int u,int fa)
{
for(int i = h[u];i != -1 ; i =ne[i])
{
int j =e[i];
if(j == fa) continue;
aq[j] = aq[u]^c[j];
if(j!=fa)dfs(j,u);
}
}
int main()
{
scanf("%d %d",&n,&m);
logg =(int )(log(n)/log(2)) + 1;
for(int i = 1; i <= n ; i++) h[i] = - 1;
for(int i = 1 ; i <= n ; i++) cin >> c[i];
for(int i = 1 ; i < n ; i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
bfs();
aq[1] = c[1];
dfs(1,0);
for(int i = 1 ; i <= m ; i++)
{
int x,y;
scanf("%d %d",&x,&y);
int sb =lca(x,y);
// cout << sb << endl;
printf("%d\n",c[sb]^aq[x]^aq[y]);
}
return 0;
}