題目
恕我直言,這個題用倍增的都是xx
抄WXH代碼的在線點分樹,寫的真是好啊。
但是線性基要用__builtin_clzll優化,快3倍之後纔可以和倍增理論上複雜度優越。
。。。。。。
以後我就這麼寫點分了。
#include<bits/stdc++.h>
#define maxn 20005
#define inf 0x3f3f3f3f
#define LL long long
#define pb push_back
#define FOR(a)\
for(vector<int>::iterator i=a[u].begin();i!=a[u].end();i++)
using namespace std;
int n,q;
LL f[16][maxn][61],tf[61],G[maxn];
vector<int>e1[maxn],e2[maxn];
int rt,Min,tsz,sz[maxn],d[maxn],fa[maxn],vis[maxn];
void ins(LL *f,LL v){
for(;v;){
int i=63-__builtin_clzll(v);
if(f[i]) v^=f[i];
else f[i] = v, v=0;
}
}
void dfs1(int u,int ff,int v=0,int Max=0){
sz[u]=1;
FOR(e1)
if((v=*i)!=ff && !vis[v])
dfs1(v,u) , Max = max(Max , sz[v]) , sz[u] += sz[v];
if(Min>(Max=max(Max,tsz-sz[u]))) Min=Max,rt=u;
}
void dfs2(int u,int ff,LL f[][61],int v=0){
sz[u] = 1 , ins(f[u],G[u]);
FOR(e1)
if(!vis[v=*i] && v!=ff)
memcpy(f[v],f[u],sizeof (LL)*61),dfs2(v,u,f),sz[u]+=sz[v];
}
int dfs3(int u,int ff,int v=0){
Min=inf,tsz=sz[u],dfs1(u,0),u=rt,d[u]=d[fa[u]=ff]+1,dfs2(u,0,f[d[u]]),vis[u]=1;
FOR(e1)
if(!vis[v=*i])
e2[u].pb(dfs3(v,u));
return u;
}
int lca(int u,int v){ for(;u!=v;) d[u]<d[v]?v=fa[v]:u=fa[u];return u; }
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%lld",&G[i]);
for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),e1[u].pb(v),e1[v].pb(u);
sz[1]=n,dfs3(1,0);
for(int i=1,x,y;i<=q;i++){
scanf("%d%d",&x,&y);int t = lca(x,y);
memcpy(tf,f[d[t]][x],sizeof tf);
for(int j=60;~j;j--) ins(tf,f[d[t]][y][j]);
LL ans = 0;
for(int j=60;~j;j--) if((ans^tf[j])>ans) ans^=tf[j];
printf("%lld\n",ans);
}
}