分析
树上从下往上线性基合并即可
并不需要启发式/xyx
代码
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<queue> #include<ctime> #include<vector> #include<set> #include<map> #include<stack> using namespace std; #define int long long int n,m,belong[100100][31],ans[100100],val[100100],res[100100],siz[100100]; int id[100100]; vector<int>v[100100]; inline void ins(int wh,int x){ int i,j,k; for(j=30;j>=0;j--) if((1ll<<j)&x){ if(!belong[wh][j]){ belong[wh][j]=x; break; } x^=belong[wh][j]; } return; } inline void mer(int x,int y){ int i,j,k; for(j=30;j>=0;j--) if(belong[y][j])ins(x,belong[y][j]); return; } inline void dfs(int x,int fa){ int i,j,k; ins(id[x],val[x]); for(i=0;i<v[x].size();i++) if(v[x][i]!=fa){ dfs(v[x][i],x); mer(x,v[x][i]); } for(i=30;i>=0;i--) if((ans[x]^belong[id[x]][i])>ans[x])ans[x]=(ans[x]^belong[id[x]][i]); } signed main(){ int i,j,k; scanf("%lld",&n); for(i=1;i<n;i++){ int x,y; scanf("%lld%lld",&x,&y); v[x].push_back(y); v[y].push_back(x); } for(i=1;i<=n;i++)scanf("%lld",&val[i]),id[i]=i; dfs(1,0); scanf("%lld",&m); while(m--){ int x; scanf("%lld",&x); printf("%lld\n",ans[x]); } return 0; }