题目链接:https://www.luogu.org/problem/P3292
解题报告:看到异或和最大,首先想到线性基,然而是在树上的,就考虑倍增LCA然后暴力插入线性基!
AC代码:
1 #include<vector> 2 #include<cstdio> 3 #include<iostream> 4 #include<cmath> 5 #include<queue> 6 #include<stack> 7 #include<cmath> 8 #include<algorithm> 9 #define numm ch-48 10 #define pd putchar(' ') 11 #define pn putchar(' ') 12 #define pb push_back 13 #define fi first 14 #define se second 15 #define fre1 freopen("1.txt","r",stdin) 16 #define fre2 freopen("2.txt","w",stdout) 17 using namespace std; 18 template <typename T> 19 void read(T &res) { 20 bool flag=false;char ch; 21 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 22 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 23 flag&&(res=-res); 24 } 25 template <typename T> 26 void write(T x) { 27 if(x<0) putchar('-'),x=-x; 28 if(x>9) write(x/10); 29 putchar(x%10+'0'); 30 } 31 const int maxn=20010; 32 const int N=60; 33 const int inf=0x3f3f3f3f; 34 const int INF=0x7fffffff; 35 const int LOG=18; 36 typedef long long ll; 37 struct edge { 38 int v,net; 39 }e[maxn<<1]; 40 int cnt=0,head[maxn]; 41 void add(int u,int v) { 42 e[++cnt].v=v; 43 e[cnt].net=head[u]; 44 head[u]=cnt; 45 } 46 struct wtz { 47 ll p[65]; 48 void clean() { for(int i=0;i<=61;i++) p[i]=0; } 49 void add(ll x) { 50 for(int i=61;~i;i--) 51 if(x&(1LL<<i)) 52 if(!p[i]){ 53 p[i]=x; 54 break; 55 } 56 else x^=p[i]; 57 } 58 }g[maxn][20],ans; 59 int depth[maxn],f[maxn][20]; 60 void merges(wtz &x,wtz y) { ///合并线性基 61 for(int i=61;~i;i--) 62 if(y.p[i]) x.add(y.p[i]); 63 } 64 void dfs(int u,int fath) { 65 depth[u]=depth[fath]+1; 66 f[u][0]=fath; 67 for(int i=1;i<=LOG;i++) { 68 f[u][i]=f[f[u][i-1]][i-1]; 69 g[u][i]=g[u][i-1]; ///g[u][i]由g[u][i-1]和g[f[u][i-1]][i-1]两块组成 70 merges(g[u][i],g[f[u][i-1]][i-1]); 71 } 72 for(int i=head[u];~i;i=e[i].net){ 73 74 if(e[i].v!=fath) dfs(e[i].v,u); 75 76 } 77 } 78 void lca(int x,int y) { 79 if(depth[x]<depth[y]) swap(x,y); 80 for(int i=LOG;~i;i--) 81 if(depth[f[x][i]]>=depth[y]) { 82 merges(ans,g[x][i]),x=f[x][i]; 83 } 84 if(x==y) { 85 merges(ans,g[x][0]); 86 return ; 87 } 88 for(int i=LOG;~i;i--) { 89 if(f[x][i]!=f[y][i]) { 90 merges(ans,g[x][i]); 91 merges(ans,g[y][i]); 92 x=f[x][i]; 93 y=f[y][i]; 94 } 95 } 96 merges(ans,g[x][0]); 97 merges(ans,g[y][0]); 98 merges(ans,g[f[x][0]][0]); 99 } 100 int main() 101 { 102 int n,q,a,b; 103 read(n),read(q); 104 for(int i=1;i<=n;i++) 105 head[i]=-1; 106 ll x; 107 for(int i=1;i<=n;i++) { 108 read(x); 109 g[i][0].add(x); 110 } 111 for(int i=1;i<=n-1;i++) { 112 read(a),read(b); 113 add(a,b); 114 add(b,a); 115 } 116 dfs(1,0); 117 for(int i=1;i<=q;i++) { 118 ans.clean(); 119 ll res=0; 120 read(a),read(b); 121 lca(a,b); 122 for(int j=61;~j;j--) 123 if((ans.p[j]^res)>res) res^=ans.p[j]; 124 write(res);pn; 125 } 126 return 0; 127 }