题解:
倍增维护线性基
线性基合并
注意,少传参,浪费时间
//少传参
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long Lint;
const int maxn=20009;
const int u=61;
int n,TT;
Lint val[maxn];
struct BS{
Lint a[u+2];
BS(){
memset(a,0,sizeof(a));
}
void Clea(){
memset(a,0,sizeof(a));
}
}g[maxn][15],T;//u=14
int f[maxn][15]={0};
int dep[maxn]={0};
void MerNum(Lint x){
for(int j=u;j>=1;--j){
if(!(x&(1LL<<(j-1))))continue;
if(T.a[j]){
x^=T.a[j];
}else{
T.a[j]=x;break;
}
}
}
void MerBS(BS B){
for(int j=u;j>=1;--j){
if(B.a[j])MerNum(B.a[j]);
}
}
int cntedge=0;
int head[maxn]={0};
int to[maxn<<1],nex[maxn<<1];
void Addedge(int x,int y){
nex[++cntedge]=head[x];
to[cntedge]=y;
head[x]=cntedge;
}
void Dfs(int x,int fa){
f[x][0]=fa;
dep[x]=dep[fa]+1;
for(int i=head[x];i;i=nex[i]){
if(to[i]==fa)continue;
Dfs(to[i],x);
}
}
void LCAinit(){
for(int i=1;i<=n;++i){
T.Clea();
MerNum(val[i]);
MerNum(val[f[i][0]]);
g[i][0]=T;
}
for(int j=1;j<=14;++j){
for(int i=1;i<=n;++i){
f[i][j]=f[f[i][j-1]][j-1];
if(f[i][j]){
T.Clea();
MerBS(g[i][j-1]);MerBS(g[f[i][j-1]][j-1]);
g[i][j]=T;
}
}
}
}
Lint Getans(){
Lint ret=0;
for(int j=u;j>=1;--j){
if((ret^T.a[j])>ret)ret=(ret^T.a[j]);
}
return ret;
}
Lint Querymax(int u,int v){
if(u==v)return val[u];
T.Clea();
if(dep[u]<dep[v])swap(u,v);
for(int j=14;j>=0;--j){
if(dep[f[u][j]]>=dep[v]){
MerBS(g[u][j]);
u=f[u][j];
}
}
if(u==v){
return Getans();
}
for(int j=14;j>=0;--j){
if(f[u][j]!=f[v][j]){
MerBS(g[u][j]);
MerBS(g[v][j]);
u=f[u][j];v=f[v][j];
}
}
MerNum(val[u]);
MerNum(val[v]);
MerNum(val[f[u][0]]);
return Getans();
}
int main(){
scanf("%d%d",&n,&TT);
for(int i=1;i<=n;++i)scanf("%lld",&val[i]);
for(int i=1;i<=n-1;++i){
int x,y;scanf("%d%d",&x,&y);
Addedge(x,y);
Addedge(y,x);
}
Dfs(1,0);
LCAinit();
while(TT--){
int x,y;
scanf("%d%d",&x,&y);
printf("%lld
",Querymax(x,y));
}
return 0;
}