1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include<queue> #include<string> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; inline long long read(){ long long x=0,p=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') p=-1;c=getchar();} while(c<='9'&&c>='0'){x=(x<<1)+(x<<3)+(c&15);c=getchar();} return x*p; } const int N=20010; int n,m; long long V[N],res; int head[N],p; struct ss{int last,v;}G[N<<1]; void add(int a,int b){ G[++p]=(ss){head[a],b};head[a]=p; G[++p]=(ss){head[b],a};head[b]=p; } long long lb[N][19][61],ans[61]; void insert(long long *a,long long x){ for(register int i=60;i>=0;i--) if(x&(1ll<<i)) if(!a[i]){a[i]=x;return;} else x^=a[i]; } long long querymax(long long *a){ long long res=0; for(register int i=60;i>=0;--i) if((res^a[i])>res)res^=a[i]; return res; } void merge(long long *a,long long *b) {for(register int i=0;i<=60;i++)if(b[i])insert(a,b[i]);} int fa[N][19],deep[N]; void dfs(int a,int f){ fa[a][0]=f;deep[a]=deep[f]+1; for(register int i=head[a];i;i=G[i].last) if(G[i].v!=f)dfs(G[i].v,a); } void query(int a,int b){ memset(ans,0,sizeof(ans)); if(deep[a]>deep[b])swap(a,b); for(register int i=18;i>=0;i--) if(deep[a]<=deep[b]-(1<<i)) merge(ans,lb[b][i]),b=fa[b][i]; if(a==b){merge(ans,lb[a][0]);return ;} for(register int i=18;i>=0;i--)if(fa[a][i]!=fa[b][i]){ merge(ans,lb[a][i]),merge(ans,lb[b][i]); a=fa[a][i],b=fa[b][i]; } merge(ans,lb[a][0]),merge(ans,lb[b][0]); merge(ans,lb[fa[a][0]][0]); return ; } int main() { freopen("lucky.in","r",stdin); freopen("lucky.out","w",stdout); n=(int)read();m=(int)read(); for(register int i=1;i<=n;i++)V[i]=read(),insert(lb[i][0],V[i]); for(register int i=1,a,b;i<n;i++) a=read(),b=read(),add(a,b); dfs(1,0); for(register int j=1;j<=18;j++) for(register int i=1;i<=n;i++){ fa[i][j]=fa[fa[i][j-1]][j-1]; memcpy(lb[i][j],lb[i][j-1],sizeof(lb[i][j-1])); merge(lb[i][j],lb[fa[i][j-1]][j-1]); } for(register int i=1,a,b;i<=m;i++){ a=(int)read();b=(int)read(); query(a,b); printf("%lld\n",querymax(ans)); } return 0; }
|