F07【模板】01Trie P10471 最大异或对
F07【模板】01Trie 最大异或对_哔哩哔哩_bilibili
P10471 最大异或对 The XOR Largest Pair - 洛谷
题目:给定 N 个整数,选出两个进行异或计算,求最大异或和
// 01Trie O(30*n) #include<bits/stdc++.h> using namespace std; const int N=100010; int n, a[N]; int ch[N*31][2],cnt,ans; void insert(int x){ int p=0; for(int i=30; i>=0; i--){ int j=x>>i&1; //取出第i位 if(!ch[p][j])ch[p][j]=++cnt; p=ch[p][j]; } } int query(int x){ int p=0,res=0; for(int i=30; i>=0; i--){ int j=x>>i&1; if(ch[p][!j]){ res+=1<<i; //累加位权 p=ch[p][!j]; } else p=ch[p][j]; } return res; } int main(){ cin>>n; for(int i=1; i<=n; i++) cin>>a[i],insert(a[i]); for(int i=1; i<=n; i++) ans=max(ans,query(a[i])); cout<<ans; return 0; }
题目:给定一颗边权树,求最长异或路径的值。
思路:x~y的异或和=(1~x的异或和)^(1~y的异或和)。
#include<bits/stdc++.h> using namespace std; const int N=100010; int n; struct edge{int to,w,ne;}e[N*2]; int h[N],idx; int sum[N]; //sum[x]存x到根的异或和 int ch[N*31][2],cnt; void add(int a,int b,int c){ e[++idx]={b,c,h[a]}; h[a]=idx; } void dfs(int x,int fa){ for(int i=h[x];i;i=e[i].ne){ int y=e[i].to,w=e[i].w; if(y==fa)continue; sum[y]=sum[x]^w; dfs(y,x); } } void insert(int x){ int p=0; for(int i=30;i>=0;i--){ int j=x>>i&1; if(!ch[p][j])ch[p][j]=++cnt; p=ch[p][j]; } } int query(int x){ int p=0,res=0; for(int i=30;i>=0;i--){ int j=x>>i&1; if(ch[p][!j]){ res+=1<<i; p=ch[p][!j]; } else p=ch[p][j]; } return res; } int main(){ scanf("%d",&n); for(int i=1,x,y,w;i<n;i++){ scanf("%d%d%d",&x,&y,&w); add(x,y,w),add(y,x,w); } dfs(1,0); for(int i=1;i<=n;i++)insert(sum[i]); int res=0; for(int i=1;i<=n;i++)res=max(res,query(sum[i])); printf("%d\n",res); return 0; }
浙公网安备 33010602011771号