bzoj4568: [Scoi2016]幸运数字
树上倍增维护线性基。
一开始以为有什么奥妙,然而并没有。
暴力倍增地维护某点往上2^j个父亲的线性基就好了。合并线性基的时候就暴力把一个往另一个里插。
就是跑得很慢,可能太暴力了。
终于写完scoi2016啦。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=40007;
typedef long long LL;
using namespace std;
int n,q;
LL a[N],d[N],power[61];
template<typename T>void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N],nxt[N],to[N];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
}
void insert(LL x,LL d[]) {
for(int i=60;i>=0;i--) if(x&power[i]) {
if(!d[i]) {d[i]=x; break;}
else x^=d[i];
}
}
int f[20003][15],R[N];
LL b[20003][15][61];
void dfs(int x,int fa) {
f[x][0]=fa; R[x]=R[fa]+1;
insert(a[x],b[x][0]); insert(a[f[x][0]],b[x][0]);
for(int i=1;i<15;i++) {
f[x][i]=f[f[x][i-1]][i-1];
if(R[x]-power[i]<=0) break;
for(int j=0;j<=60;j++) b[x][i][j]=b[x][i-1][j];
for(int j=0;j<=60;j++)
insert(b[f[x][i-1]][i-1][j],b[x][i]);
}
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
dfs(to[i],x);
}
}
LL qry() {
LL res=0;
for(int i=60;i>=0;i--)
if((res^d[i])>res) res=res^d[i];
return res;
}
LL get_ans(int x,int y) {
for(int i=0;i<=60;i++) d[i]=0;
insert(a[x],d); insert(a[y],d);
if(R[x]<R[y]) swap(x,y);
for(int i=14;i>=0;i--)
if(R[f[x][i]]>=R[y]) {
for(int j=0;j<=60;j++)
insert(b[x][i][j],d);
x=f[x][i];
}
for(int i=14;i>=0;i--)
if(f[x][i]!=f[y][i]) {
for(int j=0;j<=60;j++) {
insert(b[x][i][j],d);
insert(b[y][i][j],d);
}
x=f[x][i]; y=f[y][i];
}
if(x!=y) {
x=f[x][0];
insert(a[x],d);
}
return qry();
}
int main() {
read(n); read(q);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<n;i++) {
int u,v;
read(u); read(v);
add(u,v);
}
power[0]=1;
for(int i=1;i<=60;i++) power[i]=power[i-1]*2;
dfs(1,0);
while(q--) {
int x,y;
read(x); read(y);
printf("%lld\n",get_ans(x,y));
}
return 0;
}
/*
5 1
4 5 4 9 10
2 1
3 2
4 1
5 3
4 5
*/