裸题练习模板
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int maxn=40010; vector<ll>v[maxn][16]; int d[maxn],n,Q,fa[maxn][16],last[maxn],pre[maxn],other[maxn],t; void add(int x,int y){++t;pre[t]=last[x];last[x]=t;other[t]=y;} ll x,q[maxn]; vector<ll> uni(vector<ll> a,vector<ll> b){ vector<ll>ans; int top=0,lena=a.size(),lenb=b.size(); for(int i=0;i<lena;++i)q[++top]=a[i]; for(int i=0;i<lenb;++i)q[++top]=b[i]; int p=0; for(int j=60;j>=0;--j){ bool flag=0; for(int i=p+1;i<=top;++i) if((q[i]>>j)&1){ swap(q[i],q[++p]); flag=1;break; } if(!flag)continue; for(int i=1;i<=top;++i) if(i!=p){ if((q[i]>>j)&1)q[i]^=q[p]; } } for(int i=1;i<=p;++i)ans.push_back(q[i]); return ans; } void dfs(int x){ for(int i=last[x];i;i=pre[i]){ int v=other[i]; if(v==fa[x][0])continue; d[v]=d[x]+1;fa[v][0]=x; dfs(v); } } int lca(int x,int y){ if(d[x]<d[y])swap(x,y); for(int i=15;i>=0;--i) if(d[fa[x][i]]>=d[y])x=fa[x][i]; if(x==y)return x; for(int i=15;i>=0;--i) if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } int jump(int x,int y){ for(int i=15;i>=0;--i){ if((1<<i)&y)x=fa[x][i]; } return x; } vector<ll> qs(int x,int y){ int k=log2(d[x]-d[y]+1); return uni(v[x][k],v[jump(x,d[x]-d[y]+1-(1<<k))][k]); } int main(){ cin>>n>>Q; for(int i=1;i<=n;++i){ scanf("%lld",&x); v[i][0].push_back(x); } int a,b,tmp; for(int i=1;i<n;++i){ scanf("%d%d",&a,&b); add(a,b);add(b,a); } dfs(1); for(int j=1;j<=15;++j) for(int i=1;i<=n;++i){ fa[i][j]=fa[fa[i][j-1]][j-1]; v[i][j]=uni(v[i][j-1],v[fa[i][j-1]][j-1]); } while(Q--){ scanf("%d%d",&a,&b); tmp=lca(a,b); vector<ll>ans=uni(qs(a,tmp),qs(b,tmp)); ll res=0,siz=ans.size(); for(int i=0;i<siz;++i) if((res^ans[i])>res)res^=ans[i]; printf("%lld\n",res); } return 0; }