嗯今年的省选题……我才不是从省选颓到现在才把它写了呢哼唧
嗯……其实这题真的就是标准的模板套模板啊┑(°Д °)┍
倍增模板里套个线性基……都不难写【但是一般都用链剖写lca的我毫不犹豫写跪了倍增lca【助けて下さいQuQ
嗯……脑子是个好东西……感觉写了这道题智力--一定是我太辣鸡【望天
嗯对……调了好几天的原因啊 EXCITING
-LCA写挂了智力-=INF
-在线性基的merge那儿忘了开 long long【嗯没错就是一个不起眼的小地方哼,define int long long 拯救世界xxx
-哦……线性基的合并要剪枝……身为智障我毫不犹豫地……嗯……60*60的常数开满了……【学习常数优化原来辣么重要OTL
嗯……虽然写的丑但我就是要放代码哼唧反正只比yjq慢……嗯…………那么几秒嘛………………嗯就几秒……【bzoj续一秒大法好xxx
#include<bits/stdc++.h>
#define MAXN 20057
using namespace std; int n,m;
struct t1{
long long gay[65];
void init(long long x){
memset(gay,0,sizeof(gay));
for(int i=63;~i;--i) if(x&(1ll<<i))
{ gay[i]=x; break; }
}
}dt[MAXN];
inline void merge(t1 &z,const t1 &x, const t1 &y){
z=y;
for(int i=63;~i;--i){
long long k=x.gay[i];
for(int j=i;~j;--j){
if(z.gay[j]){
if(k&(1ll<<j)) k^=z.gay[j];
}
else if(k&(1ll<<j)){
z.gay[j]=k;
break;
}
}
}
}
struct t2{
int to,nxt;
}edge[MAXN<<1]; int cnt_edge=0;
int fst[MAXN];
void addedge(int x,int y){
edge[++cnt_edge].to=y;
edge[cnt_edge].nxt=fst[x];
fst[x]=cnt_edge;
}
int anc[MAXN][18];
t1 rec[MAXN][18];
void jump(int x){
for(int i=0;i<17;++i)
anc[x][i+1]=anc[anc[x][i]][i],
merge(rec[x][i+1], rec[x][i],rec[anc[x][i]][i]);
}
int dpt[MAXN];
void dfs(int now){
jump(now);
for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
if(edge[tmp].to==anc[now][0]) continue;
int son=edge[tmp].to;
anc[son][0]=now;
rec[son][0]=dt[son];
dpt[son]=dpt[now]+1;
dfs(son);
}
}
long long work(int u,int v){
t1 rtn; memset(rtn.gay,0,sizeof(rtn.gay));
int d1=dpt[u],d2=dpt[v];
if(d1<d2) swap(u,v),swap(d1,d2);
for(int i=17;~i;--i) if(dpt[anc[u][i]]>=d2)
merge(rtn, rec[u][i],rtn), u=anc[u][i];
if(u!=v){
for(int i=17;~i;--i){
if(anc[u][i]!=anc[v][i])
merge(rtn, rec[v][i],rtn), merge(rtn, rec[u][i],rtn),
u=anc[u][i],v=anc[v][i];
if(u==v) break;
}
merge(rtn, dt[u],rtn), merge(rtn, dt[v],rtn);
merge(rtn, dt[anc[u][0]],rtn);
}
else merge(rtn, dt[u],rtn);
long long k=0;
for(int i=63;~i;--i)
if((rtn.gay[i]^k)>k) k^=rtn.gay[i];
return k;
}
int main(){
freopen("1.in","r",stdin);
freopen("orz.out","w",stdout);
memset(dt,0,sizeof(dt));
memset(anc,0,sizeof(anc));
scanf("%d%d",&n,&m);
int x,y;
long long kk;
for(int i=1;i<=n;++i) scanf("%lld",&kk), dt[i].init(kk);
for(int i=1;i<n;++i)
scanf("%d%d",&x,&y), addedge(x,y),addedge(y,x);
dpt[1]=0;
anc[1][0]=1;
dfs(1);
for(int i=1;i<=m;++i)
scanf("%d%d",&x,&y), printf("%lld\n",work(x,y));
return 0;
}