调了半天感觉代码没错,不知道是不是思路假了。
思路:对于每个点处理出当前点到根节点的前缀线性基,记 posx,i 为当前点 x 的前缀线性基的第 i 为的贡献最近来自哪。询问的时候就是两个到最近公共祖先的线性基异或起来。
大概是这样,但是不知道为啥 0pts。
代码:
#include <bits/stdc++.h>
using namespace std;
namespace IO
{
char buff[1<<21],*p1=buff,*p2=buff;
char getch(){return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;}
template<typename T>
void read(T &x){char ch=getch();int fl=1;x=0;while(ch>'9'||ch<'0'){if(ch=='-')fl=-1;ch=getch();}while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getch();}x*=fl;}
template<typename T,typename ...Args>
void read(T &x,Args& ...args){read(x);read(args...);}
char obuf[1<<21],*p3=obuf;
void putch(char ch) {if(p3-obuf<(1<<21))*p3++=ch;else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=ch;}
char ch[100];
template<typename T>
void write(T x) {if(!x)return putch('0');if(x<0)putch('-'),x*=-1;int top=0;while(x)ch[++top]=x%10+48,x/=10;while(top)putch(ch[top]),top--;}
template<typename T,typename ...Args>
void write(T x,Args ...args) {write(x);write(args...);}
void put(string s){for(int i=0;i<s.size();i++)putch(s[i]);}
void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;
const int N=2e4+5,P=65;
int n,q,v[N];
int dep[N],top[N],siz[N],son[N],fa[N];
int id[N],cnt;
vector<int> V[N];
struct PIS{
int pos[P],p[P];
void init(){
memset(pos,0,sizeof(pos));memset(p,0,sizeof(p));
}
void insert(int id,int x){
for(int i=61;i>=0;i--){
if((x>>i)&1){
if(p[i]){
if(pos[i]<id) swap(pos[i],id),swap(x,p[i]);
x^=p[i];
}
else{
p[i]=x;pos[i]=id;
break;
}
}
}
}
int query(int g,int res){
int ans=res;
for(int i=61;i>=0;i--){
if(pos[i]>=dep[g]) ans=max(ans,ans^p[i]);
}
return ans;
}
}a[N];
void dfs1(int x,int f){
fa[x]=f;siz[x]=1;dep[x]=dep[f]+1;
int fat=-1;
for(auto v:V[x]){
if(v==f) continue;
dfs1(v,x);
siz[x]+=siz[v];
if(siz[v]>fat) fat=siz[v],son[x]=v;
}
}
void dfs2(int x,int tp){
top[x]=tp;id[x]=++cnt;
for(int i=0;i<=61;i++){
a[x].p[i]=a[fa[x]].p[i];
a[x].pos[i]=a[fa[x]].pos[i];
}
a[x].insert(dep[x],v[x]);
if(!son[x]) return;
dfs2(son[x],tp);
for(auto v:V[x]){
if(v==son[x] || v==fa[x]) continue;
dfs2(v,v);
}
}
int Lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]>dep[y]?y:x;
}
signed main(){
// freopen("P3292_1.in","r",stdin);
// freopen("1.out","w",stdout);
read(n,q);
for(int i=1,x;i<=n;i++) read(v[i]);
for(int i=1,u,v;i<n;i++){
read(u,v);
V[u].push_back(v);
V[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
int x,y;
while(q--){
read(x,y);
int l=Lca(x,y);
int ans=a[x].query(l,0);
ans=a[y].query(l,ans);
// cout << x << " " << y << "\n";
write(ans);putch('\n');
}
flush();
return 0 ;
}