题目大意:就是给你一棵树,每个树上的节点都有一个权值,现在给你一个询问u和v问你这个路径上面挑任意几个数进行xor运算,问你xor最大值是多少
解题思路:对于每个点我们可以维护它向根节点上面走 2 i 2^i 2i次方步数的线性基的信息那么我们就可以在查询的时候往上跳,边跳边合并
#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define hash Hash
#define next Next
#define pb push_back
#define f first
#define s second
#define y1 Y
using namespace std;
const int N = 2e4 + 10, mod = 1e9 + 7;
const int maxn = 2e4 + 10;
const int MAXL = 61;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
const int BUF=30000000;
char Buf[BUF],*buf=Buf;
template<typename T> void read(T &a)
{
for(a=0;*buf<48;buf++);
while(*buf>47) a=a*10+ *buf++ -48;
}
template<typename T, typename... Args> void read(T &first, Args& ... args)
{
read(first);
read(args...);
}
ll node[maxn];
vector<int> G[maxn];
int n, q;
struct LinearBasis
{
long long a[MAXL + 1];
LinearBasis(){fill(a, a + MAXL + 1, 0);}
LinearBasis(long long *x, int n) {build(x, n);}
void init() {ms(a,0);}
void insert(long long t) {
for (int j = MAXL; j >= 0; j--) {
if (!t) return;
if (!(t & (1ll << j))) continue;
if (a[j]) t ^= a[j];
else {
for (int k = 0; k < j; k++) if (t & (1ll << k)) t ^= a[k];
for (int k = j + 1; k <= MAXL; k++) if (a[k] & (1ll << j)) a[k] ^= t;
a[j] = t;
break;
}
}
}
void build(long long *x, int n) {
fill(a, a + MAXL + 1, 0);
for (int i = 1; i <= n; i++) {
insert(x[i]);
}
}
long long queryMax() {
long long res = 0;
for (int i = 0; i <= MAXL; i++) res ^= a[i];
return res;
}
void mergeFrom(const LinearBasis &other) {
for (int i = 0; i <= MAXL; i++) insert(other.a[i]);
}
static LinearBasis merge(const LinearBasis &a, const LinearBasis &b) {
LinearBasis res = a;
for (int i = 0; i <= MAXL; i++) res.insert(b.a[i]);
return res;
}
}Mul[N][17];
int fa[N][17], depth[N];
inline void dfs(int u, int f) {
fa[u][0] = f;depth[u] = depth[f] + 1;
for(int i = 1; i <= 16; ++ i)
fa[u][i] = fa[fa[u][i - 1]][i - 1];
for(int i = 1; i <= 16; ++ i)
Mul[u][i] = Mul[u][i].merge(Mul[u][i - 1],Mul[fa[u][i - 1]][i - 1]);
for(auto it : G[u]) {
if(it == f) continue;
dfs(it,u);
}
}
inline int LCA(int a, int b) {
if(depth[a] > depth[b]) swap(a,b);
int delta = depth[b] - depth[a];
for(int i = 0; i <= 16; ++ i)
if(delta >> i & 1) b = fa[b][i];
if(a == b) return a;
for(int i = 16; i >= 0; -- i)
if(fa[a][i] != fa[b][i])
a = fa[a][i], b = fa[b][i];
return fa[a][0];
}
inline LinearBasis slove(int a, int b) {
int delta = depth[a] - depth[b];
LinearBasis res;
for(int i = 0; i <= 16; ++ i)
if(delta >> i & 1)
res.mergeFrom(Mul[a][i]), a = fa[a][i];
return res;
}
int main()
{
fread(Buf,1,BUF,stdin);
read(n,q);
for(int i = 1; i <= n; ++ i)
read(node[i]),Mul[i][0].insert(node[i]);
for(int i = 1; i < n; ++ i) {
int l, r;
read(l,r);
G[l].push_back(r);
G[r].push_back(l);
}
dfs(1,0);
while(q --) {
int l, r;
read(l,r);
int lca = LCA(l,r);
LinearBasis res, ans;
res.mergeFrom(slove(l,lca));
ans.mergeFrom(slove(r,lca));
res.mergeFrom(ans);
res.mergeFrom(Mul[lca][0]);
cout << res.queryMax() << "\n";
}
return 0;
}