题目(BZOJ)
题目(洛谷)
直接倍增(打st表)维护线性基......
所以n才会给这么小啊......
#include <bits/stdc++.h> using namespace std; typedef long long ll; template <class _E> inline void read(_E &e){ e=0;bool ck=0;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')ck=1;ch=getchar();} while(isdigit(ch)){e=(e<<1)+(e<<3)+(ch^48);ch=getchar();} if(ck)e=-e; } const int N=20050; int n,Q; ll ji[N][16][70],mx[70]; int dep[N],p[N][16]; struct edge{ int vk,nxt; }e[N<<1]; int head[N],tt; inline void ad(int u,int v){e[++tt].vk=v;e[tt].nxt=head[u];head[u]=tt;} inline void addji(ll *x,ll v){ for(int i=60;i>=0;--i){ if(!(v>>i))continue; if(!x[i]){x[i]=v;break;} v^=x[i]; } } inline void mergeji(ll *x,ll *y){ for(int i=60;i>=0;--i){ if(!y[i])continue; addji(x,y[i]); } } void dfslca(int u){ for(int i=1;i<=15;++i){ for(int j=0;j<=60;++j)ji[u][i][j]=ji[u][i-1][j]; mergeji(ji[u][i],ji[p[u][i-1]][i-1]); p[u][i]=p[p[u][i-1]][i-1]; } for(int i=head[u];i;i=e[i].nxt){ int v=e[i].vk; if(v==p[u][0])continue; dep[v]=dep[u]+1; p[v][0]=u; dfslca(v); } } inline void lca(int x,int y){ if(dep[y]<dep[x])swap(x,y); for(int i=15;i>=0;--i){ if(dep[y]-(1<<i)<dep[x])continue; mergeji(mx,ji[y][i]); y=p[y][i]; } if(x==y){ mergeji(mx,ji[y][0]); return; } for(int i=15;i>=0;--i){ if(p[x][i]==p[y][i])continue; mergeji(mx,ji[x][i]);mergeji(mx,ji[y][i]); x=p[x][i],y=p[y][i]; } mergeji(mx,ji[x][0]);mergeji(mx,ji[y][0]); mergeji(mx,ji[p[y][0]][0]); } int main(){ read(n),read(Q); for(int i=1;i<=n;++i){ ll x;read(x); addji(ji[i][0],x); } for(int i=1;i<n;++i){ int u,v;read(u),read(v); ad(u,v),ad(v,u); } dfslca(1); while(Q--){ memset(mx,0,sizeof mx); int x,y;read(x),read(y); lca(x,y);ll ans=0; for(int i=60;i>=0;--i)ans=max(ans,(ans^mx[i])); printf( } return 0; }
Comments NOTHING