F07【模板】01Trie 最大异或对
视频链接:F07【模板】01Trie 最大异或对_哔哩哔哩_bilibili
// 01Trie 最大异或对 #include <iostream> using namespace std; const int N=100010; int n, a[N]; int ch[N*31][2],cnt; 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]); int ans=0; for(int i=1; i<=n; i++) ans=max(ans,query(a[i])); cout<<ans; return 0; }
// 思路:i~j的异或和=(1~i的异或和)^(1~j的异或和) #include <iostream> #include <cstring> #include <algorithm> 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; }